first commit
9
example_Shaarli-Material/.editorconfig
Normal file
@ -0,0 +1,9 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
trim_trailing_whitespace = true
|
||||
20
example_Shaarli-Material/.gitignore
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
# Sublime Text files.
|
||||
*.sublime-project
|
||||
*.sublime-workspace
|
||||
|
||||
# Removes some useless build files.
|
||||
material/dist/*
|
||||
#!material/dist
|
||||
material/opengraph.png
|
||||
|
||||
# Removes the user defined template.
|
||||
material/extra.html
|
||||
|
||||
# Removes node modules.
|
||||
node_modules
|
||||
|
||||
# Removes the HTML version of README.
|
||||
README.html
|
||||
|
||||
# Removes VS Code config that isn't useful for others.
|
||||
.vscode/settings.json
|
||||
206
example_Shaarli-Material/CHANGELOG.md
Normal file
@ -0,0 +1,206 @@
|
||||
# Change Log
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
|
||||
## unreleased
|
||||
### Added
|
||||
- New pager on link list.
|
||||
|
||||
### Removed
|
||||
- `v` prefix to the Shaarli version number in the footer.
|
||||
|
||||
### Fixed
|
||||
- Wrong image path for errors.
|
||||
|
||||
|
||||
## [v0.14.0](https://github.com/kalvn/Shaarli-Material/releases/tag/v0.14.0) - 2024-12-24
|
||||
### Added
|
||||
- Support for Shaarli v0.14.0.
|
||||
|
||||
### Changed
|
||||
- Update links on the Tools page.
|
||||
- Move from ESLint standard to neostandard for linting JS.
|
||||
|
||||
### Removed
|
||||
- Babel for transpilation.
|
||||
- Core-JS for old-browser support.
|
||||
|
||||
|
||||
## [v0.12.2](https://github.com/kalvn/Shaarli-Material/releases/tag/v0.12.2) - 2024-12-23
|
||||
### Added
|
||||
- Support for Shaarli v0.12.2 and v0.13.0.
|
||||
- Support for new core plugin ReadItLater.
|
||||
|
||||
### Removed
|
||||
- Support for Internet Explorer.
|
||||
|
||||
|
||||
## [v0.12.1](https://github.com/kalvn/Shaarli-Material/releases/tag/v0.12.1) - 2021-02-10
|
||||
### Added
|
||||
- Support for Shaarli v0.12.1.
|
||||
- Async metadata loading when adding a new link.
|
||||
- Working with URL rewriting disabled.
|
||||
- Highlight searched text in links and tags.
|
||||
- Server page which shows you details about your server config.
|
||||
- Weekly and Monthly Shaarli, in addition to the Daily.
|
||||
- Support for customized tag separator.
|
||||
- ESLint to ensure better JS code quality.
|
||||
|
||||
### Changed
|
||||
- Replaced the QR Code JS library from [qrcodejs](https://davidshimjs.github.io/qrcodejs/) to [qrcode](https://github.com/soldair/node-qrcode).
|
||||
- Improved overall localization.
|
||||
- Build system from Gulp to Rollup.
|
||||
- Redesign of error/warning/success notifications (after saving configuration for example).
|
||||
|
||||
### Fixed
|
||||
- Page unique identification.
|
||||
|
||||
### Removed
|
||||
- `config.MATERIAL_DATE_FROMNOW` option, in order to greatly reduce JS dependencies size.
|
||||
- `moment.js` JS dependency.
|
||||
- Dropped support for IE9 and IE10.
|
||||
|
||||
|
||||
## [v0.12.0](https://github.com/kalvn/Shaarli-Material/releases/tag/v0.12.0) - 2020-11-28
|
||||
### Added
|
||||
- Support for Shaarli v0.12.0.
|
||||
- Support for new page URLs.
|
||||
- `lang` attribute in `<html>` tag.
|
||||
|
||||
### Changed
|
||||
- Jump from jQuery v1.12.4 to v3.4.1. It lowers browser support to IE9+.
|
||||
- Other NPM dependencies updated.
|
||||
|
||||
### Fixed
|
||||
- An issue where the login form couldn't be displayed.
|
||||
- An issue where images where overflowing their container when markdown is enabled.
|
||||
|
||||
### Removed
|
||||
- Firefox Social API support.
|
||||
|
||||
|
||||
## [v0.11.0](https://github.com/kalvn/Shaarli-Material/releases/tag/v0.11.0) - 2020-04-08
|
||||
### Added
|
||||
- Batch mode: option to select all links on the page.
|
||||
- Batch mode: visibility settings.
|
||||
- NPM dependencies updated.
|
||||
|
||||
|
||||
## [v0.10.4](https://github.com/kalvn/Shaarli-Material/releases/tag/v0.10.4) - 2019-04-16
|
||||
### Added
|
||||
- Support of `<del>` tag in Markdown.
|
||||
|
||||
### Fixed
|
||||
- Unformatted date is now displayed instead of "Invalid date" in some cases when date format is not recognized.
|
||||
|
||||
### Changed
|
||||
- Slight design refresh.
|
||||
- Improved search overlay usability.
|
||||
- Optimized fonts loading by making text readable while loading.
|
||||
|
||||
|
||||
## [v0.10.3](https://github.com/kalvn/Shaarli-Material/releases/tag/v0.10.3) - 2019-03-29
|
||||
Be careful, one important change comes with this release: the `build` folder is not anymore part of the code repository. So if you use to update the theme with `git pull`, you now need to do
|
||||
|
||||
```bash
|
||||
$ git pull
|
||||
$ npm install
|
||||
$ gulp build
|
||||
```
|
||||
|
||||
This will install build tools and process files. I'll now attach ready-to-use built theme to each release, similarly to what is done for Shaarli.
|
||||
|
||||
**Known issue:** the build process outputs scary errors due to new version of *uncss* not understanding properly some links containing RainTPL markup. This doesn't prevent it from working properly so you can ignore.
|
||||
|
||||
### Changed
|
||||
- Processed JS and CSS files are not anymore in code repository.
|
||||
- Reorganisation of directories in order to keep `/material` directory clean.
|
||||
- Updated dependencies.
|
||||
- Updated Gulp to v4.
|
||||
- Refreshed linklist page design.
|
||||
|
||||
### Removed
|
||||
- Bower. Front-end dependencies are now also retrieved with NPM.
|
||||
|
||||
|
||||
## [v0.10.2-patch.3](https://github.com/kalvn/Shaarli-Material/releases/tag/v0.10.2-patch.3) - 2019-01-12
|
||||
### Fixed
|
||||
- Laggy popup animation.
|
||||
- Missing feedback when deleting tag.
|
||||
- Error on permalink page due to inexistant variables with Shaarli v0.10.2.
|
||||
|
||||
### Removed
|
||||
- Useless resources.
|
||||
|
||||
|
||||
## [v0.10.2-patch.2](https://github.com/kalvn/Shaarli-Material/releases/tag/v0.10.2-patch.2) - 2018-11-06
|
||||
### Fixed
|
||||
- HTML class added in the wrong place.
|
||||
- RainTPL escaping in linklist page.
|
||||
- Open Graph description containing html tags.
|
||||
|
||||
|
||||
## [v0.10.2](https://github.com/kalvn/Shaarli-Material/releases/tag/v0.10.2) - 2018-11-04
|
||||
### Added
|
||||
- Supports Shaarli v0.10.2
|
||||
- Thumbnail update page
|
||||
- Keyboard shortcut "S" displays search overlay
|
||||
|
||||
### Fixed
|
||||
- Thumbnails on link list and daily pages
|
||||
- Daily previous link not disabled properly when on oldest day
|
||||
|
||||
|
||||
## [v0.9.5](https://github.com/kalvn/Shaarli-Material/releases/tag/v0.9.5) - 2018-02-08
|
||||
### Changed
|
||||
- Optimizes bookmarklet popup size and enables scrollbars
|
||||
|
||||
### Removed
|
||||
- Redirector setting as it was removed from Shaarli core
|
||||
|
||||
### Fixed
|
||||
- Typo in the bottom link counter.
|
||||
|
||||
|
||||
## [v0.9.3](https://github.com/kalvn/Shaarli-Material/releases/tag/v0.9.3) - 2018-01-08
|
||||
### Added
|
||||
- Supports Shaarli v0.9.3 with an important security fix
|
||||
- New design for The Daily Shaarli
|
||||
|
||||
### Fixed
|
||||
- Now properly applies MATERIAL_COLOR variable
|
||||
|
||||
|
||||
## [v0.9.2](https://github.com/kalvn/Shaarli-Material/releases/tag/v0.9.2) - 2017-10-23
|
||||
### Added
|
||||
- Unique version hash appended to JS and CSS files to avoid cache issue after an update
|
||||
- *Remember me* setting is taken into account
|
||||
|
||||
### Changed
|
||||
- Modified [referrer policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy) to `cross-origin` instead of `origin-when-crossorigin`
|
||||
|
||||
### Fixed
|
||||
- Links in footer
|
||||
|
||||
|
||||
## [v0.9.1](https://github.com/kalvn/Shaarli-Material/releases/tag/v0.9.1) - 2017-10-08
|
||||
### Added
|
||||
- Tag list view
|
||||
- Creation date when editing a link
|
||||
- Filter in the toolbar to display only untagged links
|
||||
- Batch link selection and deletion
|
||||
- Icons from iconfont in toolbar, Tools page, floating add button, etc.
|
||||
- 3rd party plugins and application on Tools page
|
||||
- Icon for notes in link list
|
||||
|
||||
### Changed
|
||||
- Plugin error design is better integrated
|
||||
|
||||
### Removed
|
||||
- config.MATERIAL_COLOR, config.MATERIAL_COLOR_FOCUS and config.MATERIAL_COLOR_ACTIVE customization options. The first one is still present but only acts on a meta tag in `<head>`. They are replaced by `data/user.css` with an example in `user.example.css`.
|
||||
|
||||
### Fixed
|
||||
- Auto-complete plugin for search field is now only initialized once
|
||||
22
example_Shaarli-Material/LICENSE
Normal file
@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 kalvn
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
121
example_Shaarli-Material/README.md
Normal file
@ -0,0 +1,121 @@
|
||||
# Shaarli Material Theme
|
||||
Shaarli Material is a theme for [Shaarli](https://github.com/shaarli/Shaarli), the famous personal, minimalist, super-fast, database free, bookmarking service.
|
||||
|
||||
|
||||
## Screenshots
|
||||

|
||||
|
||||
[More screenshots](https://github.com/kalvn/Shaarli-Material/tree/master/screenshots).
|
||||
|
||||
|
||||
## Compatibility
|
||||
Shaarli Material follows the exact same versions numbers than Shaarli. It means that if you install Shaarli vX.Y.Z, you must use Shaarli Material vX.Y.Z.
|
||||
|
||||
Shaarli Material was tested and validated with **Shaarli 0.14.0**.
|
||||
|
||||
|
||||
## Download
|
||||
To download this theme, [visit this page](https://github.com/kalvn/Shaarli-Material/releases) and choose the most recent version matching the version of your Shaarli installation. Both use the same notation.
|
||||
|
||||
Versions suffixed by `-patch.x` include some bugfix so take those preferentially if they exist for the version that fits your Shaarli installation.
|
||||
|
||||
If you install an older version, please read the README.md file you'll find in the root folder rather than this one.
|
||||
|
||||
|
||||
## Installation
|
||||
Download the `material` folder into the `tpl` directory of your Shaarli installation next to the `default` directory.
|
||||
|
||||
Access your Shaarli and finish the setup process. Then, go into menu **Tools > Configure your Shaarli** and change the setting **Theme** to **Material**.
|
||||
|
||||
You can now enjoy your new Material theme.
|
||||
|
||||
|
||||
## Customization
|
||||
### Configuration
|
||||
You can customize a few things using the `data/config.json.php` file of your Shaarli installation. If the file doesn't exist, just create it. Be careful to respect the JSON format notation (end lines with a comma except for the last item, just before the closing curly brace), otherwise you'll get errors.
|
||||
|
||||
Here are parameters you can set.
|
||||
|
||||
- `config.MATERIAL_PHP_DATE_PATTERN` (optional): Customizes the date format. Check this to know what to write: https://php.net/manual/function.strftime.php (ex: `"%d/%m/%Y"` will output for example '30/05/2015').
|
||||
- `config.MATERIAL_NO_QRCODE` (optional): Removes the QR code control of the theme. To completely get rid of QR Codes, you of course need to disable the qrcode plugin as well.
|
||||
- `config.MATERIAL_COLOR` (optional): Customizes the theme's colors. It's used for example on Android for notification bar. It will generate `<meta name="theme-color" content="YOURCOLORHERE">`.
|
||||
|
||||
|
||||
Here is an example of what you can configure (in real life, there will be other parameters in the file, just add those to the different categories):
|
||||
|
||||
```json
|
||||
{
|
||||
"resource": {
|
||||
"raintpl_tpl": "tpl\/material\/"
|
||||
},
|
||||
|
||||
"config": {
|
||||
"MATERIAL_PHP_DATE_PATTERN": "%d\/%m\/%Y %H:%M:%S",
|
||||
"MATERIAL_NO_QRCODE": true,
|
||||
"MATERIAL_COLOR": "#607D8B"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Custom Open Graph image
|
||||
[Open Graph](https://ogp.me/#metadata) is a protocol that enables web site developers to attach rich metadata that will be used when sharing a link on social medias for example.
|
||||
|
||||
Shaarli Material supports adding a custom image that will be used by default when no image is attached to a shared link.
|
||||
|
||||
To add yours, create a PNG image and save it as `tpl/material/opengraph.png`.
|
||||
|
||||
### Custom CSS
|
||||
You can add your own CSS rules in file `data/user.css`. You'll find an example that shows how to change the whole theme color in `user.example.css`.
|
||||
|
||||
|
||||
## Add custom resources
|
||||
If you want to add your custom scripts or styles (for example analytics script), you must create a new template named `extra.html` in the *material* folder.
|
||||
Then, anything you add in this file will be included at the end of the `<head>` tag.
|
||||
|
||||
This file is NOT commited on the repository, which allows you to update the theme without overriding this file.
|
||||
|
||||
|
||||
## Plugins
|
||||
As from Shaarli v0.6.0, you can install plugins to enrich your experience.
|
||||
Most of them should work properly, although it's up to the plugin developer to ensure the code is as minimal as possible to integrates well in custom themes.
|
||||
I tested all plugins available with Shaarli 0.6.0 and they all work well even though the display is a bit weird for some of them. I will keep monitoring the behavior of popular plugins in the future.
|
||||
|
||||
|
||||
## Libraries used
|
||||
This theme uses a few JavaScript libraries.
|
||||
|
||||
- [jQuery](http://jquery.com/)
|
||||
- [Bootstrap](http://getbootstrap.com/)
|
||||
- [awesomplete](http://leaverou.github.io/awesomplete/)
|
||||
- [blazy](http://dinbror.dk/blazy/)
|
||||
- [Sortable](http://rubaxa.github.io/Sortable/)
|
||||
- [Salvattore](https://salvattore.js.org/)
|
||||
- [Autosize](https://github.com/jackmoore/autosize/)
|
||||
- [node-qrcode](https://github.com/soldair/node-qrcode)
|
||||
|
||||
|
||||
## Demo
|
||||
A read-only demo is available on my personal Shaarli : [https://links.kalvn.net](https://links.kalvn.net)
|
||||
|
||||
|
||||
## Develop and debug
|
||||
To tweak this theme, you'll need to install dependencies and to build JavaScript and CSS libraries. To do this, install [Node.js and NPM](https://nodejs.org) and run this from the root folder:
|
||||
|
||||
```bash
|
||||
$ npm install
|
||||
$ npm run dev
|
||||
```
|
||||
|
||||
|
||||
## Build for production
|
||||
|
||||
```bash
|
||||
$ npm install
|
||||
$ npm run build
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
You can download Shaarli via the Github project page: https://github.com/shaarli/Shaarli
|
||||
|
||||
Original project page: http://sebsauvage.net/wiki/doku.php?id=php:shaarli
|
||||
18
example_Shaarli-Material/eslint.config.js
Normal file
@ -0,0 +1,18 @@
|
||||
import neostandard from 'neostandard';
|
||||
|
||||
export default [
|
||||
...neostandard({
|
||||
semi: true,
|
||||
ts: false
|
||||
}),
|
||||
{
|
||||
rules: {
|
||||
'no-undef': 'off',
|
||||
'n/no-callback-literal': 'off'
|
||||
},
|
||||
ignores: [
|
||||
'node_modules/*',
|
||||
'material/dist/*'
|
||||
]
|
||||
}
|
||||
];
|
||||
18
example_Shaarli-Material/material/404.html
Normal file
@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
|
||||
<head>
|
||||
{$pageName="404"}
|
||||
{include="includes"}
|
||||
</head>
|
||||
<body>
|
||||
{include="page.header"}
|
||||
<div class="container">
|
||||
<div class="text-center">
|
||||
<img src="{$asset_path}/dist/img/sad_star.png#" alt="Nothing found">
|
||||
</div>
|
||||
<div class="nothing-found">{'Sorry, nothing to see here.'|t} That's a <strong>404</strong>.</div>
|
||||
<p class="text-center">{$error_message}</p>
|
||||
</div>
|
||||
{include="page.footer"}
|
||||
</body>
|
||||
</html>
|
||||
62
example_Shaarli-Material/material/addlink.html
Normal file
@ -0,0 +1,62 @@
|
||||
<!DOCTYPE html>
|
||||
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
|
||||
<head>
|
||||
{$pageName="addlink"}
|
||||
{include="includes"}
|
||||
</head>
|
||||
<body onload="document.addform.post.focus();">
|
||||
{include="page.header"}
|
||||
<div id="headerform" class="page-add container">
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<form method="GET" action="{$base_path}/admin/shaare" name="addform" class="form-add card">
|
||||
<div class="card-title">{"Shaare a new link"|t}</div>
|
||||
<div class="card-body">
|
||||
<div class="form-entry">
|
||||
<label for="post">{'URL or leave empty to post a note'|t}</label><br/>
|
||||
<input type="text" name="post" id="post" class="autofocus" placeholder="Type a url...">
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<button type="submit" class="button-raised button-primary pull-right">{'Add link'|t}</button>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<button type="button" class="button pull-right button-batch-addform"><i class="mdi mdi-playlist-plus" aria-hidden="true"></i> {'BULK CREATION'|t}</button>
|
||||
<div class="clearfix"></div>
|
||||
|
||||
<form class="card batch-addform hidden" method="POST" action="{$base_path}/admin/shaare-batch" name="batch-addform">
|
||||
<div class="card-header">{"Shaare multiple new links"|t}</div>
|
||||
<div class="card-body">
|
||||
<div class="form-entry">
|
||||
<label for="urls">{'Add one URL per line to create multiple bookmarks.'|t}</label>
|
||||
<textarea name="urls" id="urls" rows="4"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="form-entry">
|
||||
<label for="tags">{'Tags'|t}</label><br/>
|
||||
<input type="text" name="tags" id="tags" class="lf_input" data-list="{loop="$tags"}{$key}, {/loop}" data-multiple data-autofirst autocomplete="off">
|
||||
</div>
|
||||
|
||||
<input type="hidden" name="private" value="0">
|
||||
<div class="form-entry">
|
||||
<input type="checkbox" name="private" {if="$default_private_links"} checked="checked"{/if} id="lf_private" class="filled-in"/>
|
||||
<label for="lf_private">{'Private'|t}</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-footer">
|
||||
<input type="hidden" name="token" value="{$token}">
|
||||
<button type="submit" class="button-raised button-primary pull-right">{'Add links'|t}</button>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{include="page.footer"}
|
||||
</body>
|
||||
</html>
|
||||
35
example_Shaarli-Material/material/changepassword.html
Normal file
@ -0,0 +1,35 @@
|
||||
<!DOCTYPE html>
|
||||
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
|
||||
<head>
|
||||
{$pageName="changepassword"}
|
||||
{include="includes"}
|
||||
</head>
|
||||
<body>
|
||||
{include="page.header"}
|
||||
<div class="container page-changepassword">
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<form method="POST" action="#" name="changepasswordform" id="changepasswordform" class="card">
|
||||
<div class="card-title">{'Change password'|t}</div>
|
||||
<div class="card-body">
|
||||
<div class="form-entry">
|
||||
<label for="oldpassword">{'Current password'|t}</label>
|
||||
<input type="password" name="oldpassword" id="oldpassword" class="autofocus">
|
||||
</div>
|
||||
<div class="form-entry">
|
||||
<label for="setpassword">{'New password'|t}</label>
|
||||
<input type="password" name="setpassword" id="setpassword">
|
||||
</div>
|
||||
<input type="hidden" name="token" value="{$token}">
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<button type="submit" name="Save" class="button-raised button-primary pull-right">{'Change'|t}</button>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{include="page.footer"}
|
||||
</body>
|
||||
</html>
|
||||
65
example_Shaarli-Material/material/changetag.html
Normal file
@ -0,0 +1,65 @@
|
||||
<!DOCTYPE html>
|
||||
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
|
||||
<head>
|
||||
{$pageName="changetag"}
|
||||
{include="includes"}
|
||||
</head>
|
||||
<body>
|
||||
{include="page.header"}
|
||||
<div class="container page-changetag">
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<form method="POST" action="" name="changetag" id="changetag" class="card">
|
||||
<div class="card-title">{"Manage tags"|t}</div>
|
||||
<div class="card-body">
|
||||
<input type="hidden" name="token" value="{$token}">
|
||||
<p>All modifications are case sensitive.</p>
|
||||
|
||||
<div class="form-entry">
|
||||
<label for="fromtag">Modify this tag…</label>
|
||||
<input type="text" name="fromtag" id="fromtag" value="{$fromtag}" class="autofocus"
|
||||
autocomplete="off" data-multiple data-minChars="1"
|
||||
data-list="{loop="$tags"}{$key}, {/loop}"/>
|
||||
|
||||
</div>
|
||||
<div class="form-entry">
|
||||
<label for="totag">…into this tag</label>
|
||||
<input type="text" name="totag" id="totag">
|
||||
</div>
|
||||
<p>{'You can also edit tags in the'|t} <a href="{$base_path}/tags/list?sort=usage">{'tag list'|t}</a>.</p>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<button type="submit" id="button-delete" name="deletetag" class="button-raised button-alert pull-right" value="Delete tag">{'Delete tag'|t}</button>
|
||||
<button type="submit" name="renametag" class="button-raised pull-right" value="Rename tag">{'Rename tag'|t}</button>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<form method="POST" action="{$base_path}/admin/tags/change-separator" name="changeseparator" id="changeseparator" class="card">
|
||||
<div class="card-header">{"Change tags separator"|t}</div>
|
||||
<div class="card-body">
|
||||
<p>
|
||||
{'Your current tag separator is'|t} <code>{$tags_separator}</code>{if="!empty($tags_separator_desc)"} ({$tags_separator_desc}){/if}.
|
||||
</p>
|
||||
<div class="form-entry">
|
||||
<label for="separator">{'New separator'|t}</label>
|
||||
<input type="text" name="separator" id="separator" autocomplete="off"/>
|
||||
<input type="hidden" name="token" value="{$token}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<p>
|
||||
{'Note that hashtags won\'t fully work with a non-whitespace separator.'|t}
|
||||
</p>
|
||||
<button type="submit" name="saveseparator" class="button-raised button-primary pull-right">{'Save'|t}</button>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{include="page.footer"}
|
||||
</body>
|
||||
</html>
|
||||
242
example_Shaarli-Material/material/configure.html
Normal file
@ -0,0 +1,242 @@
|
||||
<!DOCTYPE html>
|
||||
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
|
||||
<head>
|
||||
{$pageName="configure"}
|
||||
{include="includes"}
|
||||
</head>
|
||||
<body>
|
||||
{include="page.header"}
|
||||
<div class="container page-configure">
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<form method="POST" action="#" name="configform" id="configform" class="card">
|
||||
<input type="hidden" name="token" value="{$token}"/>
|
||||
<div class="card-title">Configuration</div>
|
||||
<div class="card-body">
|
||||
<div class="form-entry">
|
||||
<label for="title">Shaarli {'title'|t}</label>
|
||||
<input type="text" name="title" id="title" class="autofocus" size="50" value="{$title}" />
|
||||
</div>
|
||||
<div class="form-entry">
|
||||
<label for="titleLink">{'Home link'|t}</label>
|
||||
<input type="text" name="titleLink" id="titleLink" size="50" value="{$titleLink}">
|
||||
<div class="sublabel">{'Default value'|t}: {$base_path}/</div>
|
||||
</div>
|
||||
<div class="form-entry">
|
||||
<label for="theme">{'Theme'|t}</label>
|
||||
<select name="theme" id="theme">
|
||||
{loop="$theme_available"}
|
||||
<option value="{$value}" {if="$value === $theme"}selected{/if}>
|
||||
{$value|ucfirst}
|
||||
</option>
|
||||
{/loop}
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-entry">
|
||||
<label for="theme">{'Description formatter'|t}</label>
|
||||
<select name="formatter" id="formatter">
|
||||
{loop="$formatter_available"}
|
||||
<option value="{$value}" {if="$value === $formatter"}selected="selected"{/if}>
|
||||
{$value|ucfirst}
|
||||
</option>
|
||||
{/loop}
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-entry">
|
||||
<label for="language">{'Language'|t}</label>
|
||||
<select name="language" id="language">
|
||||
{loop="$languages"}
|
||||
<option value="{$key}" {if="$key === $language"}selected{/if}>
|
||||
{$value|ucfirst}
|
||||
</option>
|
||||
{/loop}
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-entry">
|
||||
<label for="continent">{'Timezone'|t}</label>
|
||||
<div class="row">
|
||||
<div class="col-sm-6" id="timezone-continent">
|
||||
<select name="continent" id="continent">
|
||||
{loop="$continents"}
|
||||
{if="$key !== 'selected'"}
|
||||
<option value="{$value}" {if="$continents.selected === $value"}selected{/if}>
|
||||
{$value}
|
||||
</option>
|
||||
{/if}
|
||||
{/loop}
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-sm-6" id="timezone-city">
|
||||
<select name="city" id="city">
|
||||
{loop="$cities"}
|
||||
{if="$key !== 'selected'"}
|
||||
<option value="{$value.city}" {if="$cities.selected === $value.city"}selected{/if} data-continent="{$value.continent}">
|
||||
{$value.city}
|
||||
</option>
|
||||
{/if}
|
||||
{/loop}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sublabel">{'Continent'|t} · {'City'|t}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="list-side-right">
|
||||
<div class="list-body">
|
||||
<div class="list-item">
|
||||
<div class="list-item-content">
|
||||
<div class="list-item-label">{'Disable session cookie hijacking protection'|t}</div>
|
||||
<div class="list-item-sublabel">{'Check this if you get disconnected or if your IP address changes often'|t}</div>
|
||||
</div>
|
||||
<div class="list-item-side">
|
||||
<div class="switch">
|
||||
<label>
|
||||
<input type="checkbox" name="disablesessionprotection" id="disablesessionprotection" {if="$session_protection_disabled"}checked{/if}/>
|
||||
<span class="lever"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="list-item">
|
||||
<div class="list-item-content">
|
||||
<div class="list-item-label">{'Private links by default'|t}</div>
|
||||
<div class="list-item-sublabel">{'All new links are private by default'|t}</div>
|
||||
</div>
|
||||
<div class="list-item-side">
|
||||
<div class="switch">
|
||||
<label>
|
||||
<input type="checkbox" name="privateLinkByDefault" id="privateLinkByDefault" {if="$private_links_default"}checked{/if}/>
|
||||
<span class="lever"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="list-item">
|
||||
<div class="list-item-content">
|
||||
<div class="list-item-label">{'RSS direct links'|t}</div>
|
||||
<div class="list-item-sublabel">Enabling it will show a permalink in the description, and the feed item will be linked to the absolute URL. Disabling it swaps this behaviour around (permalink in title and link in description).</div>
|
||||
</div>
|
||||
<div class="list-item-side">
|
||||
<div class="switch">
|
||||
<label>
|
||||
<input type="checkbox" name="enableRssPermalinks" id="enableRssPermalinks" {if="$enable_rss_permalinks"}checked{/if}/>
|
||||
<span class="lever"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="list-item">
|
||||
<div class="list-item-content">
|
||||
<div class="list-item-label">{'Hide public links'|t}</div>
|
||||
<div class="list-item-sublabel">{'Do not show any links if the user is not logged in'|t}</div>
|
||||
</div>
|
||||
<div class="list-item-side">
|
||||
<div class="switch">
|
||||
<label>
|
||||
<input type="checkbox" name="hidePublicLinks" id="hidePublicLinks" {if="$hide_public_links"}checked{/if}/>
|
||||
<span class="lever"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="list-item">
|
||||
<div class="list-item-content">
|
||||
<div class="list-item-label">{'Automatically retrieve description for new bookmarks'|t}</div>
|
||||
<div class="list-item-sublabel">{'Shaarli will try to retrieve the description from meta HTML headers'|t}</div>
|
||||
</div>
|
||||
<div class="list-item-side">
|
||||
<div class="switch">
|
||||
<label>
|
||||
<input type="checkbox" name="retrieveDescription" id="retrieveDescription" {if="$retrieve_description"}checked{/if}/>
|
||||
<span class="lever"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="list-item">
|
||||
<div class="list-item-content">
|
||||
<div class="list-item-label">{'Check updates'|t}</div>
|
||||
<div class="list-item-sublabel">{'Notify me when a new release is ready'|t}</div>
|
||||
</div>
|
||||
<div class="list-item-side">
|
||||
<div class="switch">
|
||||
<label>
|
||||
<input type="checkbox" name="updateCheck" id="updateCheck" {if="$enable_update_check"}checked{/if}/>
|
||||
<span class="lever"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="list-item">
|
||||
<div class="list-item-content">
|
||||
<div class="list-item-label">{'Enable thumbnails'|t}</div>
|
||||
<div class="list-item-sublabel">
|
||||
{if="! $gd_enabled"}
|
||||
{'You need to enable the extension <code>php-gd</code> to use thumbnails.'|t}
|
||||
{elseif="$thumbnails_enabled"}
|
||||
<a href="{$base_path}/admin/thumbnails">{'Synchronize thumbnails'|t}</a>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
<div class="list-item-side">
|
||||
<select name="enableThumbnails" id="enableThumbnails" class="align">
|
||||
<option value="all" {if="$thumbnails_mode=='all'"}selected{/if}>
|
||||
{'All'|t}
|
||||
</option>
|
||||
<option value="common" {if="$thumbnails_mode=='common'"}selected{/if}>
|
||||
{'Only common media hosts'|t}
|
||||
</option>
|
||||
<option value="none" {if="$thumbnails_mode=='none'"}selected{/if}>
|
||||
{'None'|t}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="list-item">
|
||||
<div class="list-item-content">
|
||||
<div class="list-item-label">{'Enable REST API'|t}</div>
|
||||
<div class="list-item-sublabel">{'Allow third party software to use Shaarli such as mobile application'|t}</div>
|
||||
</div>
|
||||
<div class="list-item-side">
|
||||
<div class="switch">
|
||||
<label>
|
||||
<input type="checkbox" name="enableApi" id="enableApi" {if="$api_enabled"}checked{/if}/>
|
||||
<span class="lever"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="list">
|
||||
<div class="list-item">
|
||||
<div class="form-entry">
|
||||
<label for="apiSecret">{'API secret'|t}</label>
|
||||
<input type="text" name="apiSecret" id="apiSecret" size="50" value="{$api_secret}" placeholder="Type a random string..." />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-footer">
|
||||
<button type="submit" name="Save" class="button-raised button-primary pull-right">{'Save'|t}</button>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{include="page.footer"}
|
||||
</body>
|
||||
</html>
|
||||
116
example_Shaarli-Material/material/daily.html
Normal file
@ -0,0 +1,116 @@
|
||||
<!DOCTYPE html>
|
||||
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
|
||||
<head>
|
||||
{$pageName="daily"}
|
||||
{include="includes"}
|
||||
</head>
|
||||
<body class="dark-toolbar">
|
||||
{include="page.header"}
|
||||
|
||||
<div class="subheader is-dark">
|
||||
<div class="container text-center">
|
||||
<a class="button-inverse button-default{if="array_key_exists('day', $_GET) || (!array_key_exists('week', $_GET) && !array_key_exists('month', $_GET))"} active{/if}" href="{$base_path}/daily?day" title="{'Daily'|t}">{'Daily'|t}</a>
|
||||
<a class="button-inverse button-default{if="array_key_exists('week', $_GET)"} active{/if}" href="{$base_path}/daily?week" title="{'Weekly'|t}">{'Weekly'|t}</a>
|
||||
<a class="button-inverse button-default{if="array_key_exists('month', $_GET)"} active{/if}" href="{$base_path}/daily?month" title="{'Monthly'|t}">{'Monthly'|t}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="daily">
|
||||
<div id="plugin_zone_start_picwall" class="plugin_zone">
|
||||
{loop="$plugin_start_zone"}
|
||||
{$value}
|
||||
{/loop}
|
||||
</div>
|
||||
|
||||
<div class="daily-header">
|
||||
<h1>{$localizedType} Shaarli</h1>
|
||||
<p class="daily-header-subtitle">{function="t('All links of one :type in a single page.', '', 1, 'shaarli', [':type' => t($type)])"}</p>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<a {if="$previousday"}href="{$base_path}/daily?{$type}={$previousday}"{else}href="#"{/if} class="button" {if="!$previousday"}disabled{/if}>
|
||||
<i class="mdi mdi-arrow-left"></i> {function="t('Previous :type', '', 1, 'shaarli', [':type' => t($type)], true)"}
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-xs-6">
|
||||
<a {if="$nextday"}href="{$base_path}/daily?{$type}day={$nextday}"{else}href="#"{/if} class="button" {if="!$nextday"}disabled{/if}>
|
||||
{function="t('Next :type', '', 1, 'shaarli', [':type' => t($type)], true)"} <i class="mdi mdi-arrow-right"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr class="darker">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 class="daily-title">{$dayDesc}</h2>
|
||||
|
||||
<div id="plugin_zone_about_daily" class="plugin_zone">
|
||||
{loop="$daily_about_plugin"}
|
||||
{$value}
|
||||
{/loop}
|
||||
</div>
|
||||
|
||||
{if="$linksToDisplay"}
|
||||
<div class="daily-grid clearfix" data-columns>
|
||||
{loop="$linksToDisplay"}
|
||||
{$link=$value}
|
||||
<div class="daily-item">
|
||||
<div class="daily-card">
|
||||
<a href="{$link.real_url}" class="daily-item-header ripple ripple-primary">
|
||||
{$link.title}
|
||||
</a>
|
||||
|
||||
{if="$thumbnails_enabled && !empty($link.thumbnail)"}
|
||||
<div class="daily-item-image" style="background-image: url({$root_path}/{$link.thumbnail}#)"></div>
|
||||
{/if}
|
||||
|
||||
{if="$link.formatedDescription"}
|
||||
<div class="daily-item-body">
|
||||
{$link.formatedDescription}
|
||||
</div>
|
||||
{/if}
|
||||
<div class="daily-item-footer clearfix">
|
||||
{if="!$hide_timestamps || $is_logged_in"}
|
||||
<a href="{$base_path}/shaare/{$value.shorturl}" class="daily-item-footer-subtitle" title="{'Permalink'|t}">
|
||||
{if="$type === 'week'"}
|
||||
{function="strftime('%a %e %b, %H:%M', $link.timestamp)"}
|
||||
{else}
|
||||
{if="$type === 'month'"}
|
||||
{function="strftime('%a %e %b %Y, %H:%M', $link.timestamp)"}
|
||||
{else}
|
||||
{function="strftime('%H:%M', $link.timestamp)"}
|
||||
{/if}
|
||||
{/if}
|
||||
</a>
|
||||
{/if}
|
||||
{if="$link.tags"}
|
||||
<div class="daily-item-tags">
|
||||
{$tags=implode(', ', $link['taglist'])}
|
||||
{$tags}
|
||||
</div>
|
||||
{/if}
|
||||
<div>
|
||||
{loop="$link.link_plugin"}
|
||||
{$value}
|
||||
{/loop}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/loop}
|
||||
</div>
|
||||
{else}
|
||||
<div>No articles on this day.</div>
|
||||
{/if}
|
||||
|
||||
<div id="plugin_zone_end_picwall" class="plugin_zone">
|
||||
{loop="$plugin_end_zone"}
|
||||
{$value}
|
||||
{/loop}
|
||||
</div>
|
||||
</div>
|
||||
{include="page.footer"}
|
||||
</body>
|
||||
</html>
|
||||
35
example_Shaarli-Material/material/dailyrss.html
Normal file
@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss version="2.0">
|
||||
<channel>
|
||||
<title>{$localizedType} - {$title}</title>
|
||||
<link>{$index_url}</link>
|
||||
<description>{function="t('All links of one :type in a single page.', '', 1, 'shaarli', [':type' => t($type)])"}</description>
|
||||
<language>{$language}</language>
|
||||
<copyright>{$index_url}</copyright>
|
||||
<generator>Shaarli</generator>
|
||||
|
||||
{loop="$days"}
|
||||
<item>
|
||||
<title>{$value.date_human} - {$title}</title>
|
||||
<guid>{$value.absolute_url}</guid>
|
||||
<link>{$value.absolute_url}</link>
|
||||
<pubDate>{$value.date_rss}</pubDate>
|
||||
<description><![CDATA[
|
||||
{loop="$value.links"}
|
||||
<h3><a href="{$value.url}">{$value.title}</a></h3>
|
||||
<small>
|
||||
{if="!$hide_timestamps"}{$value.created|format_date} — {/if}
|
||||
<a href="{$index_url}shaare/{$value.shorturl}">{'Permalink'|t}</a>
|
||||
{if="$value.tags"} — {$value.tags}{/if}
|
||||
<br>
|
||||
{$value.url}
|
||||
</small><br>
|
||||
{if="$value.thumbnail"}<img src="{$index_url}{$value.thumbnail}#" alt="thumbnail" />{/if}<br>
|
||||
{if="$value.description"}{$value.description}{/if}
|
||||
<br><hr>
|
||||
{/loop}
|
||||
]]></description>
|
||||
</item>
|
||||
{/loop}
|
||||
</channel>
|
||||
</rss><!-- Cached version of {$page_url} -->
|
||||
44
example_Shaarli-Material/material/editlink.batch.html
Normal file
@ -0,0 +1,44 @@
|
||||
<!DOCTYPE html>
|
||||
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
|
||||
<head>
|
||||
{$pageName="editlinkbatch"}
|
||||
{include="includes"}
|
||||
</head>
|
||||
<body class="page-edit-link-batch">
|
||||
{include="page.header"}
|
||||
|
||||
<div id="progress-overlay" class="fullscreen hidden">
|
||||
<div class="content-fullscreen">
|
||||
<div class="container">
|
||||
<div class="mbl row">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<div class="is-inverted">
|
||||
<div class="progress-counter">
|
||||
<span class="progress-current">0</span> / <span class="progress-total"></span>
|
||||
</div>
|
||||
<div class="progress-bar">
|
||||
<div class="progress-actual"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-center">
|
||||
<button type="submit" name="save_edit_batch" class="button-raised button-primary">{'Save all'|t}</button>
|
||||
</div>
|
||||
|
||||
{loop="$links"}
|
||||
{$index=$key}
|
||||
{include="editlink"}
|
||||
{/loop}
|
||||
|
||||
<div class="text-center">
|
||||
<button type="submit" name="save_edit_batch" class="button-raised button-primary">{'Save all'|t}</button>
|
||||
</div>
|
||||
|
||||
{include="page.footer"}
|
||||
</body>
|
||||
</html>
|
||||
99
example_Shaarli-Material/material/editlink.html
Normal file
@ -0,0 +1,99 @@
|
||||
{if="empty($batch_mode)"}
|
||||
<!DOCTYPE html>
|
||||
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
|
||||
<head>
|
||||
{$pageName="editlink"}
|
||||
{include="includes"}
|
||||
</head>
|
||||
<body {if="!empty($_GET['source']) && $_GET['source']=='bookmarklet'"}class="from-bookmarklet"{/if}>
|
||||
{include="page.header"}
|
||||
{else}
|
||||
{ignore}Lil hack: when included in a loop in batch mode, `$value` is assigned by RainTPL with template vars.{/ignore}
|
||||
{function="extract($value) ? '' : ''"}
|
||||
{/if}
|
||||
{$asyncLoadClass=$link_is_new && $async_metadata && empty($link.title) ? 'loading-wrapper' : ''}
|
||||
{if="!isset($index)"}
|
||||
{$index=""}
|
||||
{/if}
|
||||
<div id="editlinkform{$index}" class="editlinkform container page-edit">
|
||||
<div class="row editlinkform-row">
|
||||
<div class="col-md-6 col-md-offset-3 editlinkform-col">
|
||||
<form method="post" name="linkform" class="card" action="{$base_path}/admin/shaare">
|
||||
{if="isset($link.id)"}
|
||||
<input type="hidden" name="lf_id" value="{$link.id}">
|
||||
{/if}
|
||||
<input type="hidden" name="token" value="{$token}">
|
||||
<input type="hidden" name="source" value="{$source}">
|
||||
{if="$http_referer"}
|
||||
<input type="hidden" name="returnurl" value="{$http_referer}">
|
||||
{/if}
|
||||
|
||||
<div class="card-header">
|
||||
{if="!$link_is_new"}Edit a link{else}Add a new link{/if}
|
||||
{if="!$link_is_new"}<span class="card-subheader"> - {'created on'|t} {$link.created|format_date}</span>{/if}
|
||||
<button type="button" class="button-expand button-header visible-md visible-lg" title="Expand / reduce width"></button>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="form-entry">
|
||||
<label for="lf_url{$index}">{'URL'|t}</label><br/>
|
||||
<input type="text" name="lf_url" id="lf_url{$index}" value="{$link.url}" placeholder="Type a url...">
|
||||
</div>
|
||||
<div class="form-entry">
|
||||
<label for="lf_title{$index}">{'Title'|t}</label><br/>
|
||||
<div class="{$asyncLoadClass}">
|
||||
<input type="text" name="lf_title" id="lf_title{$index}" {if="empty($batch_mode) && $link.title==''"}class="autofocus"{/if} value="{$link.title}" placeholder="Title...">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-entry">
|
||||
<label for="lf_description{$index}">{'Description'|t}</label><br/>
|
||||
<div class="{$asyncLoadClass}">
|
||||
<textarea name="lf_description" id="lf_description{$index}" {if="empty($batch_mode) && $link.description==''"}class="autofocus"{/if} placeholder="Describe the link..." rows="4">{$link.description}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-entry">
|
||||
<label for="lf_tags{$index}">{'Tags'|t}</label><br/>
|
||||
<div class="{$asyncLoadClass}">
|
||||
<input type="text" id="lf_tags{$index}" name="lf_tags" {if="empty($batch_mode)"}class="autofocus"{/if} value="{$link.tags}" class="lf_input"
|
||||
data-list="{loop="$tags"}{$key}, {/loop}" data-multiple autocomplete="off" />
|
||||
</div>
|
||||
</div>
|
||||
{if="isset($edit_link_plugin)"}
|
||||
{loop="$edit_link_plugin"}
|
||||
<div class="form-entry">
|
||||
{$value}
|
||||
</div>
|
||||
{/loop}
|
||||
{/if}
|
||||
<div class="form-entry">
|
||||
<input type="checkbox" class="filled-in" {if="$link.private === true"}checked="checked"{/if} name="lf_private" id="lf_private{$index}"/>
|
||||
<label for="lf_private{$index}">{'Private'|t}</label>
|
||||
</div>
|
||||
{if="$formatter==='markdown'"}
|
||||
<div class="form-entry">
|
||||
{'Description will be rendered with'|t}
|
||||
<a href="http://daringfireball.net/projects/markdown/syntax" title="{'Markdown syntax documentation'|t}">
|
||||
{'Markdown syntax'|t}
|
||||
</a>.
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<button type="submit" name="save_edit" class="button-raised button-primary pull-right">{'Save'|t}</button>
|
||||
{if="!$link_is_new"}
|
||||
<a href="{$base_path}/admin/shaare/delete?id={$link.id}&token={$token}"
|
||||
name="delete_link" class="button-raised button-alert">{'Delete'|t}</a>
|
||||
{/if}
|
||||
{if="!empty($batch_mode)"}
|
||||
<button type="button" name="cancel-batch-link" title="{'Remove this bookmark from batch creation/modification.'|t}" class="button pull-right ripple-primary">{'Cancel'|t}</button>
|
||||
{/if}
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{if="empty($batch_mode)"}
|
||||
{include="page.footer"}
|
||||
{/if}
|
||||
</body>
|
||||
</html>
|
||||
29
example_Shaarli-Material/material/error.html
Normal file
@ -0,0 +1,29 @@
|
||||
<!DOCTYPE html>
|
||||
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
|
||||
<head>
|
||||
{$pageName="error"}
|
||||
{include="includes"}
|
||||
</head>
|
||||
<body>
|
||||
{include="page.header"}
|
||||
|
||||
<div id="pageError" class="container text-center">
|
||||
<h2>{$message}</h2>
|
||||
|
||||
<div>
|
||||
<img src="{$asset_path}/dist/img/sad_star.png#" alt="">
|
||||
</div>
|
||||
|
||||
{if="!empty($text)"}
|
||||
<p>{$text}</p>
|
||||
{/if}
|
||||
|
||||
{if="!empty($stacktrace)"}
|
||||
<pre>
|
||||
{$stacktrace}
|
||||
</pre>
|
||||
{/if}
|
||||
</div>
|
||||
{include="page.footer"}
|
||||
</body>
|
||||
</html>
|
||||
10
example_Shaarli-Material/material/export.bookmarks.html
Normal file
@ -0,0 +1,10 @@
|
||||
<!DOCTYPE NETSCAPE-Bookmark-file-1>
|
||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
|
||||
<!-- This is an automatically generated file.
|
||||
It will be read and overwritten.
|
||||
Do Not Edit! -->{ignore}The RainTPL loop is formatted to avoid generating extra newlines{/ignore}
|
||||
<TITLE>{$pagetitle}</TITLE>
|
||||
<H1>Shaarli export of {$selection} bookmarks on {$date}</H1>
|
||||
<DL><p>{loop="links"}
|
||||
<DT><A HREF="{$value.url}" ADD_DATE="{$value.timestamp}" PRIVATE="{$value.private}" TAGS="{$value.taglist}">{$value.title}</A>{if="$value.description"}{$eol}<DD>{$value.description}{/if}{/loop}
|
||||
</DL><p>
|
||||
72
example_Shaarli-Material/material/export.html
Normal file
@ -0,0 +1,72 @@
|
||||
<!DOCTYPE html>
|
||||
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
|
||||
<head>
|
||||
{$pageName="export"}
|
||||
{include="includes"}
|
||||
</head>
|
||||
<body>
|
||||
{include="page.header"}
|
||||
<div id="toolsdiv" class="container page-export">
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<form class="card" method="post" action="{$base_path}/admin/export">
|
||||
<input type="hidden" name="token" value="{$token}">
|
||||
<h1 class="card-header">{"Export Database"|t}</h1>
|
||||
<div class="list-side-right">
|
||||
<div class="list-body">
|
||||
<div class="list-item no-border">
|
||||
<div class="list-item-content">
|
||||
<div class="list-item-label">{'Prepend note permalinks with this Shaarli instance\'s URL'|t}</div>
|
||||
<div class="list-item-sublabel">{'Useful to import bookmarks in a web browser'|t}</div>
|
||||
</div>
|
||||
<div class="list-item-side">
|
||||
<div class="switch">
|
||||
<label>
|
||||
<input type="checkbox" name="prepend_note_url" id="prepend_note_url"/>
|
||||
<span class="lever"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list-item">
|
||||
<label class="list-item-content" for="selection-all">
|
||||
<div class="list-item-label">Export all</div>
|
||||
<div class="list-item-sublabel">Export all links</div>
|
||||
</label>
|
||||
<div class="list-item-side">
|
||||
<input name="selection" class="with-gap" type="radio" value="all" id="selection-all" checked />
|
||||
<label for="selection-all"></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list-item no-border">
|
||||
<label class="list-item-content" for="selection-public">
|
||||
<div class="list-item-label">Export public</div>
|
||||
<div class="list-item-sublabel">Export public links only</div>
|
||||
</label>
|
||||
<div class="list-item-side">
|
||||
<input name="selection" class="with-gap" type="radio" value="public" id="selection-public" />
|
||||
<label for="selection-public"></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list-item no-border">
|
||||
<label class="list-item-content" for="selection-private">
|
||||
<div class="list-item-label">Export private</div>
|
||||
<div class="list-item-sublabel">Export private links only</div>
|
||||
</label>
|
||||
<div class="list-item-side">
|
||||
<input name="selection" class="with-gap" type="radio" value="private" id="selection-private" />
|
||||
<label for="selection-private"></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer clearfix">
|
||||
<button type="submit" class="button-raised button-primary pull-right">{'Export'|t}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{include="page.footer"}
|
||||
</body>
|
||||
</html>
|
||||
42
example_Shaarli-Material/material/feed.atom.html
Normal file
@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<feed xmlns="http://www.w3.org/2005/Atom">
|
||||
<title>{$pagetitle}</title>
|
||||
<subtitle>Shaared links</subtitle>
|
||||
{if="$show_dates"}
|
||||
<updated>{$last_update}</updated>
|
||||
{/if}
|
||||
<link rel="self" href="{$self_link}#" />
|
||||
<link rel="search" type="application/opensearchdescription+xml" href="{$index_url}open-search#"
|
||||
title="Shaarli search - {$shaarlititle}" />
|
||||
{loop="$plugins_feed_header"}
|
||||
{$value}
|
||||
{/loop}
|
||||
<author>
|
||||
<name>{$pagetitle}</name>
|
||||
<uri>{$index_url}</uri>
|
||||
</author>
|
||||
<id>{$index_url}</id>
|
||||
<generator>Shaarli</generator>
|
||||
{loop="$links"}
|
||||
<entry>
|
||||
<title>{$value.title}</title>
|
||||
{if="$usepermalinks"}
|
||||
<link href="{$value.guid}#" />
|
||||
{else}
|
||||
<link href="{$value.url}#" />
|
||||
{/if}
|
||||
<id>{$value.guid}</id>
|
||||
{if="$show_dates"}
|
||||
<published>{$value.pub_iso_date}</published>
|
||||
<updated>{$value.up_iso_date}</updated>
|
||||
{/if}
|
||||
<content type="html" xml:lang="{$language}"><![CDATA[{$value.description}]]></content>
|
||||
{loop="$value.taglist"}
|
||||
<category scheme="{$index_url}?searchtags=" term="{$value|strtolower}" label="{$value}" />
|
||||
{/loop}
|
||||
{loop="$value.feed_plugins"}
|
||||
{$value}
|
||||
{/loop}
|
||||
</entry>
|
||||
{/loop}
|
||||
</feed>
|
||||
39
example_Shaarli-Material/material/feed.rss.html
Normal file
@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>{$pagetitle}</title>
|
||||
<link>{$index_url}</link>
|
||||
<description>Shaared links</description>
|
||||
<language>{$language}</language>
|
||||
<copyright>{$index_url}</copyright>
|
||||
<generator>Shaarli</generator>
|
||||
<atom:link rel="self" href="{$self_link}" />
|
||||
<atom:link rel="search" type="application/opensearchdescription+xml" href="{$index_url}open-search#"
|
||||
title="Shaarli search - {$shaarlititle}" />
|
||||
{loop="$plugins_feed_header"}
|
||||
{$value}
|
||||
{/loop}
|
||||
{loop="$links"}
|
||||
<item>
|
||||
<title>{$value.title}</title>
|
||||
<guid isPermaLink="{if="$usepermalinks"}true{else}false{/if}">{$value.guid}</guid>
|
||||
{if="$usepermalinks"}
|
||||
<link>{$value.guid}</link>
|
||||
{else}
|
||||
<link>{$value.url}</link>
|
||||
{/if}
|
||||
{if="$show_dates"}
|
||||
<pubDate>{$value.pub_iso_date}</pubDate>
|
||||
<atom:modified>{$value.up_iso_date}</atom:modified>
|
||||
{/if}
|
||||
<description><![CDATA[{$value.description}]]></description>
|
||||
{loop="$value.taglist"}
|
||||
<category domain="{$index_url}?searchtags=">{$value}</category>
|
||||
{/loop}
|
||||
{loop="$value.feed_plugins"}
|
||||
{$value}
|
||||
{/loop}
|
||||
</item>
|
||||
{/loop}
|
||||
</channel>
|
||||
</rss>
|
||||
81
example_Shaarli-Material/material/import.html
Normal file
@ -0,0 +1,81 @@
|
||||
<!DOCTYPE html>
|
||||
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
|
||||
<head>
|
||||
{$pageName="import"}
|
||||
{include="includes"}
|
||||
</head>
|
||||
<body>
|
||||
{include="page.header"}
|
||||
<div id="uploaddiv" class="container page-import">
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<form method="post" action="{$base_path}/admin/import" enctype="multipart/form-data" name="uploadform" id="uploadform" class="card">
|
||||
<input type="hidden" name="token" value="{$token}">
|
||||
<input type="hidden" name="MAX_FILE_SIZE" value="{$maxfilesize}">
|
||||
<div class="card-title">{"Import Database"|t}</div>
|
||||
<div class="card-body">
|
||||
<p>Import Netscape HTML bookmarks (as exported from Firefox/Chrome/Opera/Delicious/Diigo...).</p>
|
||||
<div class="form-entry">
|
||||
<label for="filetoupload">File to upload</label>
|
||||
<input type="file" id="filetoupload" name="filetoupload" class="autofocus"/>
|
||||
<div class="sublabel">{'Maximum size allowed:'|t} <strong>{$maxfilesizeHuman}</strong></div>
|
||||
</div>
|
||||
<div class="form-entry">
|
||||
<input type="checkbox" class="filled-in" name="overwrite" id="overwrite">
|
||||
<label for="overwrite">{'Overwrite existing bookmarks'|t}</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="list-side-right">
|
||||
<div class="list-body">
|
||||
<div class="list-item">
|
||||
<label class="list-item-content" for="privacy-default">
|
||||
<div class="list-item-label">Default</div>
|
||||
<div class="list-item-sublabel">{'Use values from the imported file, default to public'|t}</div>
|
||||
</label>
|
||||
<div class="list-item-side">
|
||||
<input name="privacy" class="with-gap" type="radio" value="default" id="privacy-default" checked />
|
||||
<label for="privacy-default"></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list-item no-border">
|
||||
<label class="list-item-content" for="privacy-private">
|
||||
<div class="list-item-label">Private</div>
|
||||
<div class="list-item-sublabel">{'Import all bookmarks as private'|t}</div>
|
||||
</label>
|
||||
<div class="list-item-side">
|
||||
<input name="privacy" class="with-gap" type="radio" value="private" id="privacy-private" />
|
||||
<label for="privacy-private"></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list-item no-border">
|
||||
<label class="list-item-content" for="privacy-public">
|
||||
<div class="list-item-label">Public</div>
|
||||
<div class="list-item-sublabel">{'Import all bookmarks as public'|t}</div>
|
||||
</label>
|
||||
<div class="list-item-side">
|
||||
<input name="privacy" class="with-gap" type="radio" value="public" id="privacy-public" />
|
||||
<label for="privacy-public"></label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="list-item">
|
||||
<div class="form-entry">
|
||||
<label for="default-tags">{'Add default tags'|t}</label>
|
||||
<input type="text" name="default_tags" id="default-tags" placeholder="Separate tags with comma...">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-footer">
|
||||
<button type="submit" name="import_file" class="button-raised button-primary pull-right">{'Import'|t}</button>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{include="page.footer"}
|
||||
</body>
|
||||
</html>
|
||||
78
example_Shaarli-Material/material/includes.html
Normal file
@ -0,0 +1,78 @@
|
||||
<title>{$pagetitle}</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="format-detection" content="telephone=no" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
|
||||
<meta name="referrer" content="same-origin">
|
||||
<link rel="alternate" type="application/rss+xml" href="{$feedurl}?do=rss{$searchcrits}#" title="RSS Feed" />
|
||||
<link rel="alternate" type="application/atom+xml" href="{$feedurl}?do=atom{$searchcrits}#" title="ATOM Feed" />
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="{$asset_path}/dist/img/favicons/apple-touch-icon-57x57.png#">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="{$asset_path}/dist/img/favicons/apple-touch-icon-60x60.png#">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="{$asset_path}/dist/img/favicons/apple-touch-icon-72x72.png#">
|
||||
<link rel="apple-touch-icon" sizes="76x76" href="{$asset_path}/dist/img/favicons/apple-touch-icon-76x76.png#">
|
||||
<link rel="icon" type="image/png" href="{$asset_path}/dist/img/favicons/favicon-32x32.png#" sizes="32x32">
|
||||
<link rel="icon" type="image/png" href="{$asset_path}/dist/img/favicons/favicon-96x96.png#" sizes="96x96">
|
||||
<link rel="icon" type="image/png" href="{$asset_path}/dist/img/favicons/favicon-16x16.png#" sizes="16x16">
|
||||
<link rel="manifest" href="{$asset_path}/dist/img/favicons/manifest.json#">
|
||||
<link rel="shortcut icon" href="{$asset_path}/dist/img/favicons/favicon.ico#">
|
||||
<link rel="search" type="application/opensearchdescription+xml" href="{$base_path}/open-search#" title="Shaarli search - {$shaarlititle}"/>
|
||||
<meta name="msapplication-TileColor" content="#603cba">
|
||||
<meta name="msapplication-config" content="{$asset_path}/dist/img/favicons/browserconfig.xml#">
|
||||
{if="$pageName === 'linklist' && !empty($links) && count($links) === 1"}
|
||||
{$link=reset($links)}
|
||||
<meta property="og:title" content="{$link.title}" />
|
||||
<meta property="og:type" content="article" />
|
||||
<meta property="og:url" content="{$index_url}shaare/{$link.shorturl}" />
|
||||
{$ogDescription=isset($link.description_src) ? $link.description_src : $link.description}
|
||||
<meta property="og:description" content="{function="mb_substr(strip_tags($ogDescription), 0, 300)"}{if="strlen($ogDescription) > 300"}...{/if}" />
|
||||
{if="!empty($link.thumbnail)"}
|
||||
<meta property="og:image" content="{$index_url}{$link.thumbnail}" />
|
||||
{elseif="is_file('tpl/material/opengraph.png')"}
|
||||
<meta property="og:image" content="{$index_url}tpl/material/opengraph.png" />
|
||||
{/if}
|
||||
{if="!$hide_timestamps || $is_logged_in"}
|
||||
<meta property="article:published_time" content="{$link.created->format(DateTime::ATOM)}" />
|
||||
{if="!empty($link.updated)"}
|
||||
<meta property="article:modified_time" content="{$link.updated->format(DateTime::ATOM)}" />
|
||||
{/if}
|
||||
{/if}
|
||||
{loop="link.taglist"}
|
||||
<meta property="article:tag" content="{$value}" />
|
||||
{/loop}
|
||||
{else}
|
||||
<meta property="og:title" content="{$pagetitle}" />
|
||||
<meta property="og:type" content="website" />
|
||||
{if="is_file('tpl/material/opengraph.png')"}
|
||||
<meta property="og:image" content="{$index_url}tpl/material/opengraph.png" />
|
||||
{/if}
|
||||
{/if}
|
||||
<link type="text/css" rel="stylesheet" href="{$asset_path}/dist/lib.css?v={$version_hash}#" />
|
||||
<link type="text/css" rel="stylesheet" href="{$asset_path}/dist/bundle.css?v={$version_hash}#" />
|
||||
{if="$conf->get('config.MATERIAL_COLOR')"}
|
||||
{$themeColor=$conf->get('config.MATERIAL_COLOR')}
|
||||
<meta name="theme-color" content="{$themeColor}">
|
||||
{else}
|
||||
<meta name="theme-color" content="#2196f3">
|
||||
{/if}
|
||||
{loop="$plugins_includes.css_files"}
|
||||
<link type="text/css" rel="stylesheet" href="{$root_path}/{$value}?v={$version_hash}#"/>
|
||||
{/loop}
|
||||
{if="is_file('data/user.css')"}
|
||||
<link type="text/css" rel="stylesheet" href="{$root_path}/data/user.css#" />
|
||||
{/if}
|
||||
{$tagSeparator=str_replace("'", "\\'", $tags_separator)}
|
||||
<script>
|
||||
var shaarli = {
|
||||
source: '{$source}',
|
||||
basePath: '{$base_path}',
|
||||
rootPath: '{$root_path}',
|
||||
assetPath: '{$asset_path}',
|
||||
datePattern: '{$conf->get('config.MATERIAL_DATE_PATTERN')}',
|
||||
isAuth: {if="$is_logged_in"}true{else}false{/if},
|
||||
pageName: '{$pageName}',
|
||||
asyncMetadata: {if="isset($async_metadata) && $async_metadata"}true{else}false{/if},
|
||||
tagsSeparator: '{$tagSeparator}'
|
||||
};
|
||||
</script>
|
||||
{if="file_exists('tpl/material/extra.html')"}
|
||||
{include="extra"}
|
||||
{/if}
|
||||
78
example_Shaarli-Material/material/install.html
Normal file
@ -0,0 +1,78 @@
|
||||
<!DOCTYPE html>
|
||||
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
|
||||
<head>
|
||||
{$pageName="install"}
|
||||
{include="includes"}
|
||||
</head>
|
||||
<body>
|
||||
<div id="install" class="page-install">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<form method="post" action="{$base_path}/install" name="installform" id="installform" class="card">
|
||||
<div class="card-title">Welcome to your Shaarli</div>
|
||||
<div class="card-body">
|
||||
<p>{'It looks like it\'s the first time you run Shaarli. Please configure it.'|t}</p>
|
||||
<div class="form-entry">
|
||||
<label for="setlogin">{'Username'|t}</label>
|
||||
<input type="text" name="setlogin" id="setlogin" class="autofocus"/>
|
||||
</div>
|
||||
<div class="form-entry">
|
||||
<label for="setpassword">{'Password'|t}</label>
|
||||
<input type="password" id="setpassword" name="setpassword"/>
|
||||
</div>
|
||||
<div class="form-entry">
|
||||
<label for="continent">{'Timezone'|t}</label>
|
||||
<div class="row">
|
||||
<div class="col-sm-6" id="timezone-continent">
|
||||
<select name="continent" id="continent">
|
||||
{loop="$continents"}
|
||||
{if="$key !== 'selected'"}
|
||||
<option value="{$value}" {if="$continents.selected === $value"}selected{/if}>
|
||||
{$value}
|
||||
</option>
|
||||
{/if}
|
||||
{/loop}
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-sm-6" id="timezone-city">
|
||||
<select name="city" id="city">
|
||||
{loop="$cities"}
|
||||
{if="$key !== 'selected'"}
|
||||
<option value="{$value.city}" {if="$cities.selected === $value.city"}selected{/if} data-continent="{$value.continent}">
|
||||
{$value.city}
|
||||
</option>
|
||||
{/if}
|
||||
{/loop}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-entry">
|
||||
<label for="title">{'Shaarli title'|t}</label>
|
||||
<input type="text" name="title" id="title" placeholder="{'My links'|t}"/>
|
||||
</div>
|
||||
<div class="form-entry">
|
||||
<input type="checkbox" class="filled-in" name="updateCheck" id="updateCheck" checked="checked">
|
||||
<label for="updateCheck">{'Notify me when a new release is ready'|t}</label>
|
||||
</div>
|
||||
<div class="form-entry">
|
||||
<input type="checkbox" class="filled-in" name="enableApi" id="enableApi">
|
||||
<label for="enableApi">{'Enable REST API'|t}</label>
|
||||
<div class="sublabel">{'Allow third party software to use Shaarli such as mobile application'|t}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<button type="submit" name="Save" class="button-raised button-primary pull-right">{'Install'|t}</button>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{include="server.requirements"}
|
||||
</div>
|
||||
{include="page.footer"}
|
||||
</body>
|
||||
</html>
|
||||
152
example_Shaarli-Material/material/linklist.html
Normal file
@ -0,0 +1,152 @@
|
||||
<!DOCTYPE html>
|
||||
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
|
||||
<head>
|
||||
{$pageName="linklist"}
|
||||
{include="includes"}
|
||||
</head>
|
||||
<body>
|
||||
{include="page.header"}
|
||||
|
||||
{$dateFormat=!empty($conf->get('config.MATERIAL_PHP_DATE_PATTERN')) ? $conf->get('config.MATERIAL_PHP_DATE_PATTERN') : '%c'}
|
||||
{$qrCodeDisabled=!empty($conf->get('config.MATERIAL_NO_QRCODE')) ? $conf->get('config.MATERIAL_NO_QRCODE') : false}
|
||||
|
||||
<div id="linklist" class="container">
|
||||
{loop="$plugin_start_zone"}
|
||||
{$value}
|
||||
{/loop}
|
||||
|
||||
{include="linklist.paging"}
|
||||
|
||||
{if="count($links)==0"}
|
||||
<div class="text-center">
|
||||
<img src="{$asset_path}/dist/img/sad_star.png#" alt="Nothing found" />
|
||||
</div>
|
||||
<div class="nothing-found">Sorry... We found nothing{if="!empty($search_term)"} for <strong>{$search_term}</strong>{/if}{if="!empty($search_tags)"}{$exploded_tags=explode(' ', $search_tags)} tagged <strong>{loop="$exploded_tags"} {$value}{/loop}</strong>{/if}.</div>
|
||||
{elseif="!empty($search_term) or !empty($search_tags) or !empty($visibility) or $untaggedonly"}
|
||||
<div id="searchcriteria">
|
||||
{function="sprintf(t('%s result', '%s results', $result_count), $result_count)"}
|
||||
{if="!empty($search_term)"} {'for'|t} <strong>{$search_term}</strong>{/if}
|
||||
{if="!empty($search_tags)"}{$exploded_tags=tags_str2array($search_tags, $tags_separator)} {'tagged'|t} <i>
|
||||
{loop="$exploded_tags"}
|
||||
<a href="{$base_path}/remove-tag/{function="urlencode($value)"}" class="link-tag-filter" title="{'Remove tag'|t}">{$value}
|
||||
<span class="remove">✕</span>
|
||||
</a>
|
||||
{/loop}
|
||||
</i>
|
||||
{/if}
|
||||
{if="!empty($visibility)"}
|
||||
{'with status'|t}
|
||||
<strong>
|
||||
{$visibility|t}
|
||||
</strong>
|
||||
{/if}
|
||||
{if="$untaggedonly"}
|
||||
<strong>
|
||||
{'without any tag'|t}
|
||||
</strong>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="links-list">
|
||||
|
||||
{ignore}Set translation here, for performances{/ignore}
|
||||
{$strPrivate=t('Private')}
|
||||
{$strEdit=t('Edit')}
|
||||
{$strDelete=t('Delete')}
|
||||
{$strFold=t('Fold')}
|
||||
{$strEdited=t('Edited: ')}
|
||||
{$strPermalink=t('Permalink')}
|
||||
{$strPermalinkLc=t('permalink')}
|
||||
{$strAddTag=t('Add tag')}
|
||||
{$strToggleSticky=t('Toggle sticky')}
|
||||
{$strSticky=t('Sticky')}
|
||||
{ignore}End of translations{/ignore}
|
||||
|
||||
{loop="$links"}
|
||||
<div id="{$value.id}" class="link-outer{if="$value.class"} {$value.class}{/if}" data-id="{$value.id}">
|
||||
<div class="link-overlay"></div>
|
||||
<div class="link-inner">
|
||||
<div class="link-header">
|
||||
<div class="row">
|
||||
<div class="col-sm-8">
|
||||
<a class="link-title" href="{$value.real_url}">
|
||||
{if="strpos($value.url, $value.shorturl) !== false"}
|
||||
<i class="mdi mdi-note"></i>
|
||||
{/if}
|
||||
{$value.title_html}
|
||||
</a>
|
||||
<a href="{$value.real_url}" class="link-url"><span title="Real URL">{$value.real_url}</span></a>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<div class="link-date">
|
||||
{if="!$hide_timestamps || $is_logged_in"}
|
||||
<span title="Permalink - {function="strftime($dateFormat, $value.timestamp)"}"><a href="{$base_path}/shaare/{$value.shorturl}" class="link-actual-date">{function="strftime($dateFormat, $value.timestamp)"}</a></span>
|
||||
{else}
|
||||
<span title="Short link here"><a href="{$base_path}/shaare/{$value.shorturl}">Permalink</a></span>
|
||||
{/if}
|
||||
{loop="$value.link_plugin"}
|
||||
<span class="link-plugin">{$value}</span>
|
||||
{/loop}
|
||||
{ignore}
|
||||
{/ignore}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="link-content">
|
||||
<div>
|
||||
{if="$thumbnails_enabled && $value.thumbnail !== false"}
|
||||
<div class="thumb{if="$value.thumbnail === null"} hidden{/if}" {if="$value.thumbnail === null"}data-async-thumbnail="1"{/if}>
|
||||
<a href="{$value.real_url}">
|
||||
{ignore}RainTPL hack: put the 2 src on two different line to avoid path replace bug{/ignore}
|
||||
<img data-src="{$root_path}/{$value.thumbnail}#" class="b-lazy link-thumbnail"
|
||||
src="#"
|
||||
alt="thumbnail" width="{$thumbnails_width}" height="{$thumbnails_height}" />
|
||||
</a>
|
||||
</div>
|
||||
{/if}
|
||||
{if="$value.description"}
|
||||
<div class="link-description">{$value.description}</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
<div class="link-footer is-flex">
|
||||
<div class="link-tag-list is-flex-grown">
|
||||
{if="$value.tags"}
|
||||
{loop="$value.taglist"}
|
||||
<span class="link-tag" title="Find links with the same tag"><a href="{$base_path}/add-tag/{$value1.taglist_urlencoded.$key2}">{$value1.taglist_html.$key2}</a></span>
|
||||
{/loop}
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="link-actions is-flex-end">
|
||||
{if="!$qrCodeDisabled"}
|
||||
<a href="#" data-permalink="{$value.real_url}" title="Show link QR Code" class="qrcode"><i class="mdi mdi-qrcode"></i></a>
|
||||
{/if}
|
||||
{if="$is_logged_in"}
|
||||
<a href="{$base_path}/admin/shaare/delete?id={$value.id}&token={$token}" title="{$strDelete}" class="button-delete"><i class="mdi mdi-delete"></i></a>
|
||||
<a href="{$base_path}/admin/shaare/{$value.id}" title="{$strEdit}"><i class="mdi mdi-pencil"></i></a>
|
||||
<a href="{$base_path}/admin/shaare/{$value.id}/pin?token={$token}" title="{$strToggleSticky}" {if="isset($value.sticky) && $value.sticky"}class="is-pinned"{/if}><i class="mdi mdi-pin"></i></a>
|
||||
{else}
|
||||
{if="isset($value.sticky) && $value.sticky"}
|
||||
<span title="{$strSticky}"><i class="mdi mdi-pin"></i></span>
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/loop}
|
||||
</div>
|
||||
|
||||
{include="linklist.paging"}
|
||||
|
||||
{loop="$plugin_end_zone"}
|
||||
{$value}
|
||||
{/loop}
|
||||
</div>
|
||||
|
||||
{include="page.footer"}
|
||||
</body>
|
||||
</html>
|
||||
33
example_Shaarli-Material/material/linklist.paging.html
Normal file
@ -0,0 +1,33 @@
|
||||
{if="$page_max > 1"}
|
||||
{if="$is_logged_in"}
|
||||
{$total="$linkcount"}
|
||||
{else}
|
||||
{if="empty($privateLinkcount)"}
|
||||
{$total="$linkcount"}
|
||||
{else}
|
||||
{$total="$linkcount" - "$privateLinkcount"}
|
||||
{/if}
|
||||
{/if}
|
||||
{$from=("$page_current" - 1) * "$links_per_page" + 1}
|
||||
{$to=min($total, ("$page_current" - 1) * "$links_per_page" + "$links_per_page")}
|
||||
<div class="paging clearfix">
|
||||
<div class="paging-links">
|
||||
<div class="paging-current"><strong>{$from}-{$to}</strong> of {$total}</div>
|
||||
<!--<div class="paging-current">p<span class="hidden-xs">age</span> {$page_current} / {$page_max}</div>-->
|
||||
<div>{if="$next_page_url"}<a href="{$next_page_url}" class="paging-newer" title="Newer"><i class="mdi mdi-arrow-left"></i></a>{/if}</div>
|
||||
<div>{if="$previous_page_url"}<a href="{$previous_page_url}" class="paging-older" title="Older"><i class="mdi mdi-arrow-right"></i></a>{/if}</div>
|
||||
</div>
|
||||
<div>
|
||||
{loop="$action_plugin"}
|
||||
<div class="paging_privatelinks">
|
||||
<a
|
||||
{loop="$value.attr"}
|
||||
{$key}="{$value}"
|
||||
{/loop}>
|
||||
{$value.html}
|
||||
</a>
|
||||
</div>
|
||||
{/loop}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
43
example_Shaarli-Material/material/loginform.html
Normal file
@ -0,0 +1,43 @@
|
||||
<!DOCTYPE html>
|
||||
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
|
||||
<head>
|
||||
{$pageName="loginform"}
|
||||
{include="includes"}
|
||||
</head>
|
||||
<body>
|
||||
{include="page.header"}
|
||||
|
||||
<div id="headerform" class="page-login container">
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<form method="post" name="loginform" class="card">
|
||||
<div class="card-title">{'Login'|t}</div>
|
||||
<div class="card-body">
|
||||
<div class="form-entry">
|
||||
<label for="login">{'Username'|t}</label><br/>
|
||||
<input type="text" name="login" id="login" {if="empty($username)"}class="autofocus"{/if} tabindex="1" {if="!empty($username)"}value="{$username}"{/if}>
|
||||
</div>
|
||||
<div class="form-entry">
|
||||
<label for="password">{'Password'|t}</label><br/>
|
||||
<input type="password" name="password" id="password" {if="!empty($username)"}class="autofocus"{/if} tabindex="2" >
|
||||
</div>
|
||||
<div class="form-entry">
|
||||
<input type="checkbox" class="filled-in" name="longlastingsession" id="longlastingsession" tabindex="3"
|
||||
{if="$remember_user_default"}checked="checked"{/if}>
|
||||
<label for="longlastingsession">{'Remember me'|t}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<button type="submit" class="button-raised button-primary pull-right" tabindex="4">{'Login'|t}</button>
|
||||
<input type="hidden" name="token" value="{$token}">
|
||||
{if="$returnurl"}<input type="hidden" name="returnurl" value="{$returnurl}">{/if}
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{include="page.footer"}
|
||||
</body>
|
||||
</html>
|
||||
45
example_Shaarli-Material/material/opensearch.html
Normal file
@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
|
||||
<ShortName>Shaarli search - {$pagetitle}</ShortName>
|
||||
<Description>Shaarli search - {$pagetitle}</Description>
|
||||
<Url type="text/html" template="{$serverurl}?searchterm={searchTerms}" />
|
||||
<Url type="application/atom+xml" template="{$serverurl}feed/atom?searchterm={searchTerms}"/>
|
||||
<Url type="application/rss+xml" template="{$serverurl}feed/rss?searchterm={searchTerms}"/>
|
||||
<InputEncoding>UTF-8</InputEncoding>
|
||||
<Developer>Shaarli Community - https://github.com/shaarli/Shaarli/</Developer>
|
||||
<Image width="16" height="16">data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABmJLR0QA/wD/AP+gvaeTAAAHRklE
|
||||
QVRIx5WWaWxU5xWG3++7986dfYYZb+MN2xiMDRiDFePUiQsNoiwpUNpAmhInJVEqpa0oQUlbJVKq
|
||||
olaiqpLKUtOKhAJRm1BKRVWctuykpFjAgPcFx/uMl5mxPTOeuXPv3O3rjyiV0lIpfX+dc36c55xf
|
||||
70vwP9TZ2fFpSQCwT5u6unX4f0QeNLx27RoMQwfRveTd11T23M+8S9w+Z3NRma1W4Hk6/nEimFpM
|
||||
Xnun9Xpmz1MPY+feOhBi/fwAAOjq7iJEqmQqCZf5i7NvyNZ/bJPYgAjCiJc2Zmhyw68SM/T1+NlK
|
||||
uf61BPoH+tHU1PT5ACMjI8RXvACvpZ5NT0+fmrG+2TKqtDLV0BgA2AUfXS3+UtfDX2ixCf73E+oA
|
||||
rat92CTkv9fRBwEkSaLDt/JZR/v0Q7qjb8dQ5hjSqmYSOCkzBbogL+ij2RN8bik9wK88Al9tH4tG
|
||||
ow88lvb19yEyPwfGGLq6OungYD9fUlosrqwoQVVVUeOU8qE/mU0ZTq6KNvreNort+5hugkayQUgY
|
||||
qQld/u6qnVRhkciscOdOkNy5E0RnZ+e/AbwsZxAaHyORZA+prW01CTlnGppOqAcwUnCmlDAkAyin
|
||||
Dapb2t7lNeRijpwvTGlJROXugoKS+upz/S19Kj9lJjxXGY1VU49tGevt7WOCSMHTeAXclePsQts9
|
||||
Jq9oLR7rPVkHxpUYkK2c07ZDiieRNcAx3ZlNphcnsxbiMuEsXFSTZpabp+VVS17UNSV/8n7+gN75
|
||||
+C1DM6VEjkgatiz/5IOCAheiUdeyr+198keKZXLzTKYjMDk/ZzGJhkV9AiPSdWaYIAY4U7TYNJMR
|
||||
pugMqgHcXTiJqDK8ycMv2+TPWyWtKFw3KEdtJxNz8u8+/PNYIqeUgY/Oz+Z7q5X3gtqvG7qip8yM
|
||||
HqdZg5kGgwGACoQQQkEMQ2DMIFnGE04xCRQTZFaexUT6jEEImJ2njjxx9fr13hfqfULTQ4apHept
|
||||
lxf4mrqS3Tek0w1toTc1K6WcXfAwnyWH8kSkIueEhdhNrzUAv16fSCUzNwR3vr/G2lKWojMqbxF4
|
||||
FWlLPDvBR+RBNpTsNqfkV7htuUe/UVq456qdzzvFh2KjdSH0I6ODs1ps9NHcw2jMfRYcEQyOCiox
|
||||
aWR0fOQWVLFNUuOnrXJxfIPnpXLRKzocLpsJanhUU/bfjJ4gfwm/ys3JGX1cuS3UBvauLa/MBe9z
|
||||
5c/xGRdSKpiVmhhN98JK/w4DGgg4uLh8u1NfPhWbmzszeH3G1rxv3dL7+qXyGaXHJi46s4QQophp
|
||||
TKSDkHWGlAqmGCbAGAUA3sY5LlRZv3w44Dhnm0iFzbnsGfJR5E+EEsppTBVXuBptL5b8YQMlwnO+
|
||||
Z2wtea4cl8Rc3KXJ4zShRm0CFaCaGhSDwGSMlbtLhSr7FnVhKhscC4+AO3L0x5PSFBdfE9i40SE6
|
||||
xLSWRCIbJ6phIqEysqvk+2aJ0vhB1NK353zyaL3GS76NgRbVYykkt2OXuaQqMwuxkk0FT+OJpS+z
|
||||
piXPRP1KzRvz4dRvO68PaWCMEQAIDcbqFiLJtyaSA/Ef3NnMGttgvHS7mUUWw7cTMemtY/cPsw3n
|
||||
oe2+4mGXpt7VGWPJ6zOn1V2Xfaz5AxgvBzexodmeGWmCbWWTDOGpSZIIqeAe2/IYvnXgWbomUj2T
|
||||
lNlwUP7bV64lzuRIeoodqDxi1OKRs/e0i08dH/6JPWtk6KKaZd3xj2jAXkY3BvZGK1xrhZvRNktP
|
||||
fNA0ubQrxyxV4jHpSkWoXJPKYqBetxeRpgsMWwE5b/bxaYxUDSWmzCLbStqQuy02LY4/cWLsqH8i
|
||||
HYNbyEeJczkJSzH2855DwsXp932F9hXEKQSQ1UHa568iRAa3uFyeNVolMBmeIrzT4cTXm37KMuvA
|
||||
xb8XXTqiDELRgKg8h/dGWwP9iSDaIzcYJSCbA/uNR3N2sNahV/hbsSA70vEdW66tCOOpj8FRkIgU
|
||||
Q5ybLUopiTzeTpFWUoTXdR3knwQMzLANOyQX50fWhDktLeAX3UcIA2EEQHPgi6TBsrWzaLGm7emC
|
||||
H7bY+GPlV6YumiEpDhslxGBgROApz+yyhROzduIEzwngDh48iD3jO0nBRAUUXtHcoq+ZWbI5EWWa
|
||||
WTieFjoKsaVoN92T88J4vlz+asXqpb+hEcdotbdueZ47vyiqhpA2UoRQwpoLtpNHxR0382jR8RzT
|
||||
k8xYMyCMMfR33Uc8rxdrA9tpuHPyS7pPOTRPZ1arepa4rUsybiWnnU9a39ZXxdur+XoGAGMdoXLi
|
||||
M789axnfNxDr8omiDcvF1f3OhPf18efjF/nfz6PGvv6zlrlwWwYBgcBZbKH4WKHODLHEURDxbHDF
|
||||
QWGePftHUlZWjsy8guYnH2EgwORfZ5cuavEqgGhLnL6+sycvRP1Fbux/fheIn3wCCN4N/qdPMwA4
|
||||
2fYOeoe7kc6kcfCbh8n+r7YwAOjs6QCl9DNx5t7dew+MOf8CcuqqoLxlhwgAAAAASUVORK5CYII=
|
||||
</Image>
|
||||
</OpenSearchDescription>
|
||||
31
example_Shaarli-Material/material/page.footer.html
Normal file
@ -0,0 +1,31 @@
|
||||
<div id="footer" class="container">
|
||||
<div>
|
||||
<b><a href="https://github.com/shaarli/Shaarli">Shaarli</a></b>
|
||||
{if="$is_logged_in"} v{$version}{/if}
|
||||
- {'The personal, minimalist, super fast, database-free, bookmarking service'|t} {'by the Shaarli community'|t}
|
||||
{if="$is_logged_in"} - <a href="{$root_path}/doc/html/index.html" rel="nofollow">{'Documentation'|t}</a>{/if}
|
||||
- Theme by <a href="https://github.com/kalvn">kalvn</a>
|
||||
</div>
|
||||
<div>
|
||||
{loop="$plugins_footer.text"}
|
||||
{$value}
|
||||
{/loop}
|
||||
</div>
|
||||
{loop="$plugins_footer.endofpage"}
|
||||
{$value}
|
||||
{/loop}
|
||||
{if="$newVersion"}
|
||||
<div id="newversion"><span id="version_id">●</span> Shaarli {$newVersion} <a href="https://github.com/shaarli/Shaarli/releases">{'is available'|t}</a>.</div>
|
||||
{/if}
|
||||
{if="isset($versionError) && $versionError"}
|
||||
<div id="newversion">
|
||||
Error: {$versionError}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<input type="hidden" name="token" value="{$token}" id="token" />
|
||||
</div>
|
||||
<script src="{$asset_path}/dist/bundle.js?v={$version_hash}#"></script>
|
||||
{loop="$plugins_footer.js_files"}
|
||||
<script src="{$root_path}/{$value}?v={$version_hash}#"></script>
|
||||
{/loop}
|
||||
273
example_Shaarli-Material/material/page.header.html
Normal file
@ -0,0 +1,273 @@
|
||||
<!--
|
||||
{$isCalledFromBookmarklet=array_key_exists('source', $_GET) && in_array($_GET['source'], array('bookmarklet'))}
|
||||
{$displayAddNewLinkIcon=(($is_logged_in || $openshaarli) && in_array($pageName, array('linklist', 'tools', 'tag.cloud', 'tag.list', 'picwall', 'daily')))}
|
||||
{$plugins=$conf->get('general.enabled_plugins')}
|
||||
{$filterClass=(($visibility==='private'||$visibility==='public'||$untaggedonly)?'has-filters':'')}
|
||||
-->
|
||||
{if="$isCalledFromBookmarklet"}
|
||||
{ignore} When called as a popup from bookmarklet, do not display menu. {/ignore}
|
||||
{else}
|
||||
<div class="header-main container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-lg-3 is-flex">
|
||||
<a href="{$titleLink}" class="header-brand ripple">{$shaarlititle}</a>
|
||||
<a href="#" class="icon-unfold hidden-lg ripple" title="Show/hide menu"><i class="mdi mdi-chevron-down"></i></a>
|
||||
</div>
|
||||
<div class="col-lg-6 header-middle">
|
||||
<div class="header-nav">
|
||||
<div class="col-xs-6 col-sm-3 text-center">
|
||||
<a href="{$base_path}/tags/cloud" class="toolbar-link button-inverse ripple">{'Tag cloud'|t}</a>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-3 text-center">
|
||||
<a href="{$base_path}/picture-wall?{function="ltrim($searchcrits, '&')"}" class="toolbar-link button-inverse ripple">{'Picture wall'|t}</a>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-3 text-center">
|
||||
<a href="{$base_path}/daily" class="toolbar-link button-inverse ripple">{'Daily'|t}</a>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-3 text-center">
|
||||
<button class="toolbar-link button-inverse ripple" id="button-search">{'Search'|t}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-3">
|
||||
<div class="header-buttons">
|
||||
{if="isset($plugins_header.buttons_toolbar) ||isset($plugins_header.fields_toolbar)"}
|
||||
<div class="toolbar-button-container">
|
||||
<button type="button" class="icon-header popup-trigger ripple" data-popup="popup-plugin" title="More">
|
||||
<i class="mdi mdi-dots-vertical"></i>
|
||||
</button>
|
||||
<div id="popup-plugin" class="popup popup-plugin hidden">
|
||||
<div class="popup-title">Plugins<button class="popup-close"><i class="mdi mdi-close"></i></button></div>
|
||||
<div class="popup-body">
|
||||
{loop="$plugins_header.buttons_toolbar"}
|
||||
<ul>
|
||||
<li>
|
||||
<a
|
||||
{loop="$value.attr"}
|
||||
{$key}="{$value}"
|
||||
{/loop}>
|
||||
{$value.html}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
{/loop}
|
||||
{loop="$plugins_header.fields_toolbar"}
|
||||
<form class="popup-content-area"
|
||||
{loop="$value.attr"}
|
||||
{$key}="{$value}"
|
||||
{/loop} >
|
||||
{loop="$value.inputs"}
|
||||
<input
|
||||
{loop="$value"}
|
||||
{$key}="{$value}"
|
||||
{/loop}>
|
||||
{/loop}
|
||||
</form>
|
||||
{/loop}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{if="$is_logged_in"}
|
||||
<a href="{$base_path}/admin/logout" class="icon-header popup-trigger ripple" title="{'Logout'|t}">
|
||||
<i class="mdi mdi-logout"></i>
|
||||
</a>
|
||||
<a href="{$base_path}/admin/tools" class="icon-header ripple" title="{'Tools'|t}">
|
||||
<i class="mdi mdi-settings"></i>
|
||||
</a>
|
||||
{elseif="$openshaarli"}
|
||||
<a href="{$base_path}/admin/tools" class="icon-header ripple" title="{'Tools'|t}">
|
||||
<i class="mdi mdi-settings"></i>
|
||||
</a>
|
||||
{else}
|
||||
<a href="{$base_path}/login" class="icon-header popup-trigger ripple" title="{'Login'|t}">
|
||||
<i class="mdi mdi-account"></i>
|
||||
</a>
|
||||
{/if}
|
||||
<div class="toolbar-button-container">
|
||||
<button type="button" class="icon-header popup-trigger ripple" data-popup="popup-rss" title="{'RSS Feed'|t}">
|
||||
<i class="mdi mdi-rss"></i>
|
||||
</button>
|
||||
<div id="popup-rss" class="popup popup-rss hidden">
|
||||
<div class="popup-title">{'RSS Feed'|t}<button class="popup-close"><i class="mdi mdi-close"></i></button></div>
|
||||
<div class="popup-body">
|
||||
<ul>
|
||||
<li><a href="{$base_path}/feed/{$feed_type}?{$searchcrits}" class="ripple">{'RSS Feed'|t}</a></li>
|
||||
<li><a href="{$base_path}/daily-rss?day" class="ripple" title="1 RSS entry per day">Daily Feed</a></li>
|
||||
<li><a href="{$base_path}/daily-rss?week" class="ripple" title="1 RSS entry per day">Weekly Feed</a></li>
|
||||
<li><a href="{$base_path}/daily-rss?month" class="ripple" title="1 RSS entry per day">Monthly Feed</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{if="$is_logged_in && $pageName === 'linklist'"}
|
||||
<div class="toolbar-button-container">
|
||||
<button type="button" class="icon-header ripple batch-trigger" title="Select multiple links for deletion">
|
||||
<i class="mdi mdi-checkbox-marked-outline"></i>
|
||||
</button>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="toolbar-button-container">
|
||||
{if="$pageName === 'linklist'"}
|
||||
<button type="button" class="header-button-filter popup-trigger icon-header ripple {$filterClass}" data-popup="popup-filter" title="{'Filters'|t}">
|
||||
<i class="mdi mdi-filter"></i>
|
||||
</button>
|
||||
<div id="popup-filter" class="popup popup-filter hidden">
|
||||
<div class="popup-title">{'Filters'|t}<button class="popup-close"><i class="mdi mdi-close"></i></button></div>
|
||||
<div class="popup-body">
|
||||
<h2>{'Links per page'|t}</h2>
|
||||
<ul class="filters-links-per-page">
|
||||
<li><a href="{$base_path}/links-per-page?nb=20" class="ripple {if="$links_per_page == 20"}is-bold{/if}">20 links</a></li>
|
||||
<li><a href="{$base_path}/links-per-page?nb=50" class="ripple {if="$links_per_page == 50"}is-bold{/if}">50 links</a></li>
|
||||
<li><a href="{$base_path}/links-per-page?nb=100" class="ripple {if="$links_per_page == 100"}is-bold{/if}">100 links</a></li>
|
||||
</ul>
|
||||
<form method="get" action="{$base_path}/links-per-page" class="popup-content-area">
|
||||
<label for="filter-nb">Custom value</label>
|
||||
<input type="text" id="filter-nb" name="nb" placeholder="Type a number..." value="{$links_per_page}"/>
|
||||
</form>
|
||||
|
||||
<h2>{'Filters'|t}</h2>
|
||||
<div class="list-side-right">
|
||||
<div class="list-body">
|
||||
{if="$is_logged_in"}
|
||||
<div class="list-item">
|
||||
<div class="list-item-content">
|
||||
<div class="list-item-label">{'Only private links'|t}</div>
|
||||
</div>
|
||||
<div class="list-item-side">
|
||||
<div class="switch">
|
||||
<label data-url="{$base_path}/admin/visibility/private">
|
||||
<input type="checkbox" name="input-visibility-private" id="input-visibility-private" {if="$visibility==='private'"}checked{/if}/>
|
||||
<span class="lever"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list-item">
|
||||
<div class="list-item-content">
|
||||
<div class="list-item-label">{'Only public links'|t}</div>
|
||||
</div>
|
||||
<div class="list-item-side">
|
||||
<div class="switch">
|
||||
<label data-url="{$base_path}/admin/visibility/public">
|
||||
<input type="checkbox" name="input-visibility-public" id="input-visibility-public" {if="$visibility==='public'"}checked{/if}/>
|
||||
<span class="lever"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="list-item">
|
||||
<div class="list-item-content">
|
||||
<div class="list-item-label">{'Untagged links'|t}</div>
|
||||
</div>
|
||||
<div class="list-item-side">
|
||||
<div class="switch">
|
||||
<label data-url="{$base_path}/untagged-only">
|
||||
<input type="checkbox" name="input-untaggedonly" id="input-untaggedonly" {if="$untaggedonly"}checked{/if}/>
|
||||
<span class="lever"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{if="in_array('readitlater', $plugins)"}
|
||||
<div class="list-item">
|
||||
<div class="list-item-content">
|
||||
<div class="list-item-label">Links to read later</div>
|
||||
</div>
|
||||
<div class="list-item-side">
|
||||
<div class="switch">
|
||||
<label data-url="{$base_path}/plugin/readitlater/toggle-filter">
|
||||
<input type="checkbox" name="input-readlater" id="input-readlater" {if="$readitlaterOnly"}checked{/if}/>
|
||||
<span class="lever"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{if="$displayAddNewLinkIcon"}
|
||||
<a href="{$base_path}/admin/add-shaare" class="button-floating ripple">
|
||||
<i class="icon-add-link mdi mdi-plus"></i>
|
||||
</a>
|
||||
{/if}
|
||||
<form id="hidden-tag-form" class="hidden" method="GET" name="tagfilter" action="{$base_path}/">
|
||||
<input type="hidden" name="searchtags" id="tagfilter_value" value=""/>
|
||||
</form>
|
||||
|
||||
<div class="notifications">
|
||||
{if="!empty($plugin_errors) && $is_logged_in"}
|
||||
{loop="plugin_errors"}
|
||||
<div class="notification is-danger">
|
||||
<button class="notification-close"><i class="mdi mdi-close"></i></button>
|
||||
{$value}
|
||||
</div>
|
||||
{/loop}
|
||||
{/if}
|
||||
|
||||
{if="!empty($global_errors)"}
|
||||
{loop="global_errors"}
|
||||
<div class="notification is-danger">
|
||||
<button class="notification-close"><i class="mdi mdi-close"></i></button>
|
||||
{$value}
|
||||
</div>
|
||||
{/loop}
|
||||
{/if}
|
||||
|
||||
{if="!empty($global_warnings)"}
|
||||
{loop="global_warnings"}
|
||||
<div class="notification is-warning">
|
||||
<button class="notification-close"><i class="mdi mdi-close"></i></button>
|
||||
{$value}
|
||||
</div>
|
||||
{/loop}
|
||||
{/if}
|
||||
|
||||
{if="!empty($global_successes)"}
|
||||
{loop="global_successes"}
|
||||
<div class="notification is-success">
|
||||
<button class="notification-close"><i class="mdi mdi-close"></i></button>
|
||||
{$value}
|
||||
</div>
|
||||
{/loop}
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div id="search-overlay" class="fullscreen hidden">
|
||||
<div class="content-fullscreen">
|
||||
<div class="container">
|
||||
<div class="mbl row">
|
||||
<form method="get" action="{$base_path}/" id="form-search" class="col-md-8 col-md-offset-2">
|
||||
<div class="search-field">
|
||||
<input type="search" id="searchform_value" class="input-big" name="searchterm"
|
||||
value="{if="isset($search_type)"}{if="$search_type=='fulltext'"}{$search_crits}{elseif="$search_type=='tags'"}{loop="$search_crits"}{$value} {/loop}{else}{/if}{/if}"
|
||||
placeholder="Search..." autocomplete="off" data-multiple data-minChars="1"
|
||||
data-list="{loop="$tags"}{$key}, {/loop}" />
|
||||
<div class="search-overlay-actions">
|
||||
<button type="button" id="button-filter" class="button-raised ripple ripple-primary">
|
||||
<i class="visible-xs mdi mdi-tag-multiple"></i>
|
||||
<span class="hidden-xs"><i class="mdi mdi-magnify"></i>{'tags'|t}</span>
|
||||
</button>
|
||||
<button type="submit" id="button-search" class="button-raised button-primary ripple">
|
||||
<i class="mdi mdi-magnify"></i>
|
||||
<span class="hidden-xs">{'search'|t}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="overlay" class="overlay hidden"></div>
|
||||
12
example_Shaarli-Material/material/page.html
Normal file
@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
|
||||
<head>
|
||||
{$pageName="custom"}
|
||||
{include="includes"}
|
||||
</head>
|
||||
<body>
|
||||
{include="page.header"}
|
||||
You body goes here...
|
||||
{include="page.footer"}
|
||||
</body>
|
||||
</html>
|
||||
46
example_Shaarli-Material/material/picwall.html
Normal file
@ -0,0 +1,46 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="dark"{if="$language !== 'auto'"} lang="{$language}"{/if}>
|
||||
<head>
|
||||
{$pageName="picwall"}
|
||||
{include="includes"}
|
||||
</head>
|
||||
<body class="dark dark-toolbar">
|
||||
{include="page.header"}
|
||||
|
||||
{if="count($linksToDisplay) === 0 && $is_logged_in"}
|
||||
<div>
|
||||
{'There is no cached thumbnail.'|t}
|
||||
<a href="{$base_path}/admin/thumbnails">{'Try to synchronize them.'|t}</a>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div id="plugin_zone_start_picwall" class="plugin_zone">
|
||||
{loop="$plugin_start_zone"}
|
||||
{$value}
|
||||
{/loop}
|
||||
</div>
|
||||
<div id="picwall_container text-center" class="clearfix">
|
||||
{loop="$linksToDisplay"}
|
||||
<div class="picwall-pictureframe ripple">
|
||||
{ignore}RainTPL hack: put the 2 src on two different line to avoid path replace bug{/ignore}
|
||||
<img data-src="{$root_path}/{$value.thumbnail}#" class="b-lazy"
|
||||
src=""
|
||||
alt="thumbnail" width="{$thumbnails_width}" height="{$thumbnails_height}" />
|
||||
<a class="picwall-link" href="{$value.real_url}"><span class="info">{$value.title}</span></a>
|
||||
|
||||
{loop="$value.picwall_plugin"}
|
||||
{$value}
|
||||
{/loop}
|
||||
|
||||
</div>
|
||||
{/loop}
|
||||
</div>
|
||||
<div id="plugin_zone_end_picwall" class="plugin_zone">
|
||||
{loop="$plugin_end_zone"}
|
||||
{$value}
|
||||
{/loop}
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
{include="page.footer"}
|
||||
</body>
|
||||
</html>
|
||||
120
example_Shaarli-Material/material/pluginsadmin.html
Normal file
@ -0,0 +1,120 @@
|
||||
<!DOCTYPE html>
|
||||
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
|
||||
<head>
|
||||
{$pageName="pluginsadmin"}
|
||||
{include="includes"}
|
||||
</head>
|
||||
<body>
|
||||
{include="page.header"}
|
||||
<div id="pluginadmindiv" class="page-pluginadmin container">
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<noscript>
|
||||
<p>{'You need to enable Javascript to change plugin loading order.'|t}</p>
|
||||
</noscript>
|
||||
|
||||
<h1>{'Plugin administration'|t}</h1>
|
||||
<p>Drag and drop your plugin to change the order in which they'll be called. Uncheck enabled plugin to disable them and vice-versa.</p>
|
||||
|
||||
<form action="{$base_path}/admin/plugins" method="post">
|
||||
<input type="hidden" name="token" value="{$token}">
|
||||
<section class="card">
|
||||
<div class="card-title">{'Enabled Plugins'|t}</div>
|
||||
{if="count($enabledPlugins)==0"}
|
||||
<div class="card-body">
|
||||
<p>{'No plugin enabled.'|t}</p>
|
||||
</div>
|
||||
{else}
|
||||
<ul id="list-plugin-enabled" class="list-sortable list-checkable">
|
||||
{loop="$enabledPlugins"}
|
||||
<li class="list-item list-item-sortable" data-line="{$key}" data-order="{$counter}">
|
||||
<input type="checkbox" class="filled-in" name="{$key}" id="checkbox-{$key}" checked>
|
||||
<label for="checkbox-{$key}"></label>
|
||||
<input type="hidden" name="order_{$key}" value="{$counter}">
|
||||
<div class="list-item-content">
|
||||
<h3 class="list-item-label">{function="str_replace('_', ' ', $key)"}</h3>
|
||||
<div class="list-item-sublabel">{$value.description}</div>
|
||||
</div>
|
||||
<div class="list-sortable-handle mdi mdi-menu"></div>
|
||||
</li>
|
||||
{/loop}
|
||||
</ul>
|
||||
{/if}
|
||||
</section>
|
||||
|
||||
<section class="card">
|
||||
<div class="card-title">Disabled plugins</div>
|
||||
{if="count($disabledPlugins)==0"}
|
||||
<div class="card-body">
|
||||
<p>{'No plugin disabled.'|t}</p>
|
||||
</div>
|
||||
{else}
|
||||
<ul class="list-sortable list-checkable">
|
||||
{loop="$disabledPlugins"}
|
||||
<li class="list-item list-item-sortable" data-line="{$key}" data-order="{$counter}">
|
||||
<input type="checkbox" class="filled-in" id="checkbox-{$key}" name="{$key}">
|
||||
<label for="checkbox-{$key}"></label>
|
||||
<div class="list-item-content">
|
||||
<h3 class="list-item-label">{function="str_replace('_', ' ', $key)"}</h3>
|
||||
<div class="list-item-sublabel">{$value.description}</div>
|
||||
</div>
|
||||
</li>
|
||||
{/loop}
|
||||
</ul>
|
||||
{/if}
|
||||
</section>
|
||||
|
||||
<div class="clearfix">
|
||||
<p>
|
||||
{"More plugins available"|t}
|
||||
<a href="{$root_path}/doc/html/Community-&-Related-software/#third-party-plugins">{"in the documentation"|t}</a>.
|
||||
</p>
|
||||
<button type="submit" class="button-raised button-primary pull-right">Save plugins</button>
|
||||
</div>
|
||||
</form>
|
||||
<hr class="darker">
|
||||
<form action="{$base_path}/admin/plugins" method="post">
|
||||
<input type="hidden" name="token" value="{$token}">
|
||||
<section class="card">
|
||||
<div class="card-title">Plugin parameters</div>
|
||||
<div class="card-body">
|
||||
{if="count($enabledPlugins)==0"}
|
||||
<p>{'No plugin enabled.'|t}</p>
|
||||
{else}
|
||||
{$count=0}
|
||||
{loop="$enabledPlugins"}
|
||||
{if="count($value.parameters) > 0"}
|
||||
{if="$count>0"}
|
||||
<hr>
|
||||
{/if}
|
||||
{$count=$count+1}
|
||||
<h2>{function="str_replace('_', ' ', $key)"}</h2>
|
||||
{loop="$value.parameters"}
|
||||
<div class="row plugin-param">
|
||||
<div class="col-sm-4 plugin-param-key">
|
||||
<label for="{$key}" {if="isset($value.desc)"}title="{$value.desc}"{/if}>{function="str_replace('_', ' ', $key)"}</label>
|
||||
{if="isset($value.desc)"}<div class="sublabel">{$value.desc}</div>{/if}
|
||||
</div>
|
||||
<div class="col-sm-8">
|
||||
<input type="text" name="{$key}" value="{$value.value}" id="{$key}" {if="isset($value.desc)"}placeholder="{$value.desc}"{/if}>
|
||||
</div>
|
||||
</div>
|
||||
{/loop}
|
||||
{/if}
|
||||
{/loop}
|
||||
{if="$count==0"}
|
||||
<p>{'No parameter available.'|t}</p>
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
<div class="card-footer clearfix">
|
||||
<button type="submit" name="parameters_form" class="button-raised button-primary pull-right">Save plugin parameters</button>
|
||||
</div>
|
||||
</section>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{include="page.footer"}
|
||||
</body>
|
||||
</html>
|
||||
119
example_Shaarli-Material/material/server.html
Normal file
@ -0,0 +1,119 @@
|
||||
<!DOCTYPE html>
|
||||
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
|
||||
<head>
|
||||
{$pageName="server"}
|
||||
{include="includes"}
|
||||
</head>
|
||||
<body>
|
||||
{include="page.header"}
|
||||
|
||||
<div id="toolsdiv" class="page-server">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<h1>{'Server administration'|t}</h1>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header">{'General'|t}</div>
|
||||
<div class="card-body">
|
||||
<div class="list">
|
||||
<div class="key-value-item">
|
||||
<div>{'Index URL'|t}</div>
|
||||
<div><a href="{$index_url}" title="{$pagetitle}">{$index_url}</a></div>
|
||||
</div>
|
||||
<div class="key-value-item">
|
||||
<div>{'Base path'|t}</div>
|
||||
<div>{$base_path}</div>
|
||||
</div>
|
||||
<div class="key-value-item">
|
||||
<div>{'Client IP'|t}</div>
|
||||
<div>{$client_ip}</div>
|
||||
</div>
|
||||
<div class="key-value-item">
|
||||
<div>{'Trusted reverse proxies'|t}</div>
|
||||
<div>
|
||||
{if="count($trusted_proxies) > 0"}
|
||||
<ul>
|
||||
{loop="$trusted_proxies"}
|
||||
<li>{$value}</li>
|
||||
{/loop}
|
||||
</ul>
|
||||
{else}
|
||||
{'N/A'|t}
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{include="server.requirements"}
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<div class="card">
|
||||
<div class="card-header">{'Version'|t}</div>
|
||||
<div class="card-body">
|
||||
<div class="list">
|
||||
<div class="key-value-item">
|
||||
<div>{'Current version'|t}</div>
|
||||
<div>{$current_version}</div>
|
||||
</div>
|
||||
<div class="key-value-item">
|
||||
<div>{'Latest release'|t}</div>
|
||||
<div><a href="{$release_url}" title="{'Visit releases page on Github'|t}">{$latest_version}</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<div class="card">
|
||||
<div class="card-header">{'Thumbnails'|t}</div>
|
||||
<div class="card-body">
|
||||
<div class="list">
|
||||
<div class="key-value-item">
|
||||
<div>{'Thumbnails status'|t}</div>
|
||||
<div>
|
||||
{if="$thumbnails_mode==='all'"}
|
||||
{'All'|t}
|
||||
{elseif="$thumbnails_mode==='common'"}
|
||||
{'Only common media hosts'|t}
|
||||
{else}
|
||||
{'None'|t}
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{if="$thumbnails_mode!=='none'"}
|
||||
<div class="card-footer">
|
||||
<a href="{$base_path}/admin/thumbnails" title="{'Synchronize all link thumbnails'|t}" class="button-raised pull-right">{'Synchronize thumbnails'|t}</a>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<div class="card">
|
||||
<div class="card-header">{'Cache'|t}</div>
|
||||
<div class="card-footer">
|
||||
<a href="{$base_path}/admin/clear-cache?type=main" class="button-raised pull-right">{'Clear main cache'|t}</a>
|
||||
<a href="{$base_path}/admin/clear-cache?type=thumbnails" class="button-raised pull-right">{'Clear thumbnails cache'|t}</a>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{include="page.footer"}
|
||||
</body>
|
||||
</html>
|
||||
74
example_Shaarli-Material/material/server.requirements.html
Normal file
@ -0,0 +1,74 @@
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<div class="card">
|
||||
<div class="card-header">{'Permissions'|t}</div>
|
||||
<div class="card-body">
|
||||
{if="count($permissions) > 0"}
|
||||
<p><i class="mdi mdi-close text-error"></i> {'There are permissions that need to be fixed.'|t}</p>
|
||||
<ul>
|
||||
{loop="$permissions"}
|
||||
<li>{$value}</li>
|
||||
{/loop}
|
||||
</ul>
|
||||
{else}
|
||||
<p><i class="mdi mdi-check text-success"></i> {'All read/write permissions are properly set.'|t}</p>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-10 col-md-offset-1">
|
||||
<div class="card">
|
||||
<div class="card-header">PHP</div>
|
||||
<div class="card-body">
|
||||
<p>
|
||||
<strong>{'Running PHP'|t} {$php_version}</strong>
|
||||
|
||||
{if="$php_has_reached_eol"}
|
||||
<i class="mdi mdi-circle text-warning" aria-label="hidden"></i><br>
|
||||
{'End of life: '|t} {$php_eol}
|
||||
{else}
|
||||
<i class="mdi mdi-circle text-success" aria-label="hidden"></i><br>
|
||||
{/if}
|
||||
</p>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{'Extension'|t}</th>
|
||||
<th>{'Usage'|t}</th>
|
||||
<th>{'Status'|t}</th>
|
||||
<th class="text-center">{'Loaded'|t}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{loop="$php_extensions"}
|
||||
<tr>
|
||||
<td>{$value.name}</td>
|
||||
<td>{$value.desc}</td>
|
||||
<td>{$value.required ? t('Required') : t('Optional')}</td>
|
||||
<td class="text-center">
|
||||
{if="$value.loaded"}
|
||||
{$classLoaded="text-success"}
|
||||
{$strLoaded=t('Loaded')}
|
||||
{else}
|
||||
{$strLoaded=t('Not loaded')}
|
||||
{if="$value.required"}
|
||||
{$classLoaded="text-error"}
|
||||
{else}
|
||||
{$classLoaded="text-warning"}
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
<i class="mdi mdi-circle {$classLoaded}" aria-label="{$strLoaded}" title="{$strLoaded}"></i>
|
||||
</td>
|
||||
</tr>
|
||||
{/loop}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
35
example_Shaarli-Material/material/tag.cloud.html
Normal file
@ -0,0 +1,35 @@
|
||||
<!DOCTYPE html>
|
||||
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
|
||||
<head>
|
||||
{$pageName="tag.cloud"}
|
||||
{include="includes"}
|
||||
</head>
|
||||
<body>
|
||||
{include="page.header"}
|
||||
|
||||
{include="tag.sort"}
|
||||
|
||||
<div class="center container">
|
||||
<div id="plugin_zone_start_tagcloud" class="plugin_zone">
|
||||
{loop="$plugin_start_zone"}
|
||||
{$value}
|
||||
{/loop}
|
||||
</div>
|
||||
<div id="cloudtag">
|
||||
{loop="$tags"}
|
||||
<a href="{$base_path}/?searchtags={$tags_url.$key1}{$tags_separator|urlencode}{$search_tags_url}" style="font-size:{$value.size}em;">{$key}</a
|
||||
><span class="link-tag"><a href="{$base_path}/add-tag/{$tags_url.$key1}" title="{'Filter by tag'|t}" class="count">{$value.count}</a></span>
|
||||
{loop="$value.tag_plugin"}
|
||||
{$value}
|
||||
{/loop}
|
||||
{/loop}
|
||||
</div>
|
||||
<div id="plugin_zone_end_tagcloud" class="plugin_zone">
|
||||
{loop="$plugin_end_zone"}
|
||||
{$value}
|
||||
{/loop}
|
||||
</div>
|
||||
</div>
|
||||
{include="page.footer"}
|
||||
</body>
|
||||
</html>
|
||||
76
example_Shaarli-Material/material/tag.list.html
Normal file
@ -0,0 +1,76 @@
|
||||
<!DOCTYPE html>
|
||||
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
|
||||
<head>
|
||||
{$pageName="tag.list"}
|
||||
{include="includes"}
|
||||
</head>
|
||||
<body>
|
||||
{include="page.header"}
|
||||
|
||||
{include="tag.sort"}
|
||||
|
||||
<div class="container">
|
||||
{$countTags=count($tags)}
|
||||
|
||||
<div id="plugin_zone_start_tagcloud" class="plugin_zone">
|
||||
{loop="$plugin_start_zone"}
|
||||
{$value}
|
||||
{/loop}
|
||||
</div>
|
||||
|
||||
<div id="taglist" class="card">
|
||||
<div class="card-header">
|
||||
<div class="pull-right"><a href="{$base_path}/?searchtags={$search_tags|urlencode}" title="{'List all links with those tags'|t}">{$countTags} {'tags'|t}</a></div>
|
||||
{'Tag list'|t}
|
||||
</div>
|
||||
<form class="card-search" method="get">
|
||||
<input type="hidden" name="do" value="taglist">
|
||||
<input type="search" name="searchtags" placeholder="{'Filter by tag'|t}..."
|
||||
{if="!empty($search_tags)"}
|
||||
value="{$search_tags}"
|
||||
{/if}
|
||||
autocomplete="off" data-multiple data-autofirst data-minChars="1"
|
||||
data-list="{loop="$tags"}{$key}, {/loop}"
|
||||
>
|
||||
</form>
|
||||
{loop="tags"}
|
||||
<div class="list-item-flex is-control-opaque-hover is-highlighted-hover">
|
||||
<div class="list-item-start list-item-text">
|
||||
{$value}
|
||||
</div>
|
||||
<div class="list-item-middle list-item-text">
|
||||
<a href="{$base_path}/?searchtags={$key|urlencode} {$search_tags|urlencode}" class="tag-link">{$key}</a>
|
||||
{loop="$value.tag_plugin"}
|
||||
{$value}
|
||||
{/loop}
|
||||
</div>
|
||||
<div class="list-item-end list-item-controls">
|
||||
<a href="{$base_path}/add-tag/{$key|urlencode}" title="{'Add tag'|t} {$key} {'to the filters'|t}" class="count list-item-control">
|
||||
<i class="mdi mdi-magnify-plus-outline"></i>
|
||||
</a>
|
||||
{if="$is_logged_in"}
|
||||
<a href="{$base_path}/admin/tags?fromtag={$key|urlencode}" title="{'Rename tag'|t} {$key}" data-tag="{$key}" class="rename-tag list-item-control">
|
||||
<i class="mdi mdi-pencil"></i>
|
||||
</a>
|
||||
<a href="#" class="delete-tag list-item-control" data-tag="{$key}" title="{'Delete tag'|t} {$key}"><i class="mdi mdi-delete"></i></a>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/loop}
|
||||
</div>
|
||||
|
||||
<div id="plugin_zone_end_tagcloud" class="plugin_zone">
|
||||
{loop="$plugin_end_zone"}
|
||||
{$value}
|
||||
{/loop}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{if="$is_logged_in"}
|
||||
<input type="hidden" name="taglist" value="{loop="$tags"}{$key} {/loop}">
|
||||
{/if}
|
||||
|
||||
{include="page.footer"}
|
||||
</body>
|
||||
</html>
|
||||
|
||||
7
example_Shaarli-Material/material/tag.sort.html
Normal file
@ -0,0 +1,7 @@
|
||||
<div class="subheader">
|
||||
<div class="container text-center">
|
||||
<a class="button-inverse button-default{if="$pageName === 'tag.cloud'"} active{/if}" href="{$base_path}/tags/cloud" title="{'Cloud'|t}">{'Cloud'|t}</a>
|
||||
<a class="button-inverse button-default{if="$pageName === 'tag.list' && $_GET['sort'] === 'usage'"} active{/if}" href="{$base_path}/tags/list?sort=usage" title="{'Most used'|t}">{'Most used'|t}</a>
|
||||
<a class="button-inverse button-default{if="$pageName === 'tag.list' && $_GET['sort'] === 'alpha'"} active{/if}" href="{$base_path}/tags/list?sort=alpha" title="{'Alphabetical'|t}">{'Alphabetical'|t}</a>
|
||||
</div>
|
||||
</div>
|
||||
36
example_Shaarli-Material/material/thumbnails.html
Normal file
@ -0,0 +1,36 @@
|
||||
<!DOCTYPE html>
|
||||
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
|
||||
<head>
|
||||
{$pageName="thumbnails"}
|
||||
{include="includes"}
|
||||
</head>
|
||||
<body>
|
||||
{include="page.header"}
|
||||
<div class="page-thumbnails container">
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<div class="card">
|
||||
<h1 class="card-header">{'Thumbnails update'|t}</h1>
|
||||
<div class="card-body">
|
||||
<div class="thumbnail-placeholder" style="width: {$thumbnails_width}px; height: {$thumbnails_height}px;">
|
||||
|
||||
</div>
|
||||
<div class="thumbnail-link-title">
|
||||
Loading...
|
||||
</div>
|
||||
<div class="progress-bar">
|
||||
<div class="progress-actual"></div>
|
||||
</div>
|
||||
<div class="progress-counter">
|
||||
<span class="progress-current">0</span> / <span class="progress-total">{$ids|count}</span>
|
||||
</div>
|
||||
|
||||
<input type="hidden" name="ids" value="{function="implode(',', $ids)"}" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{include="page.footer"}
|
||||
</body>
|
||||
</html>
|
||||
240
example_Shaarli-Material/material/tools.html
Normal file
@ -0,0 +1,240 @@
|
||||
<!DOCTYPE html>
|
||||
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
|
||||
<head>
|
||||
{$pageName="tools"}
|
||||
{include="includes"}
|
||||
</head>
|
||||
<body>
|
||||
{include="page.header"}
|
||||
<div id="toolsdiv" class="page-tools container">
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<div class="card">
|
||||
<h1 class="card-header">{'Settings'|t}</h1>
|
||||
<div class="list-action list-big">
|
||||
<a class="list-item ripple" href="{$base_path}/admin/configure">
|
||||
<div class="row">
|
||||
<div class="col-sm-2 col-xs-3">
|
||||
<div class="round-image-container">
|
||||
<i class="mdi mdi-settings" title="{'Configure your Shaarli'|t}"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-10 col-xs-9">
|
||||
<div class="list-item-label">{'Configure your Shaarli'|t}</div>
|
||||
<div class="list-item-sublabel">{'Change Title, timezone...'|t}</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
{if="!$openshaarli"}
|
||||
<a class="list-item ripple" href="{$base_path}/admin/password">
|
||||
<div class="row">
|
||||
<div class="col-sm-2 col-xs-3">
|
||||
<div class="round-image-container">
|
||||
<i class="mdi mdi-lock" title="{'Change password'|t}"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-10 col-xs-9">
|
||||
<div class="list-item-label">{'Change password'|t}</div>
|
||||
<div class="list-item-sublabel">{'Change your password'|t}</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
{/if}
|
||||
<a class="list-item ripple" href="{$base_path}/admin/plugins">
|
||||
<div class="row">
|
||||
<div class="col-sm-2 col-xs-3">
|
||||
<div class="round-image-container">
|
||||
<i class="mdi mdi-puzzle" title="{'Plugin administration'|t}"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-10 col-xs-9">
|
||||
<div class="list-item-label">{'Plugin administration'|t}</div>
|
||||
<div class="list-item-sublabel">{'Enable, disable and configure plugins'|t}</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<a class="list-item ripple" href="{$base_path}/admin/server">
|
||||
<div class="row">
|
||||
<div class="col-sm-2 col-xs-3">
|
||||
<div class="round-image-container">
|
||||
<i class="mdi mdi-server" title="{'Check instance\'s server configuration'|t}"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-10 col-xs-9">
|
||||
<div class="list-item-label">{'Server administration'|t}</div>
|
||||
<div class="list-item-sublabel">{'Check instance\'s server configuration'|t}</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<a class="list-item ripple" href="{$base_path}/admin/tags">
|
||||
<div class="row">
|
||||
<div class="col-sm-2 col-xs-3">
|
||||
<div class="round-image-container">
|
||||
<i class="mdi mdi-tag-multiple" title="{'Tags'|t}"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-10 col-xs-9">
|
||||
<div class="list-item-label">{'Tags'|t}</div>
|
||||
<div class="list-item-sublabel">{'Rename or delete a tag in all links'|t}</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<a class="list-item ripple" href="{$base_path}/admin/import">
|
||||
<div class="row">
|
||||
<div class="col-sm-2 col-xs-3">
|
||||
<div class="round-image-container">
|
||||
<i class="mdi mdi-file-import" title="{'Import'|t}"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-10 col-xs-9">
|
||||
<div class="list-item-label">{'Import'|t}</div>
|
||||
<div class="list-item-sublabel">{'Import Netscape html bookmarks (as exported from Firefox, Chrome, Opera, delicious...)'|t}</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<a class="list-item ripple" href="{$base_path}/admin/export">
|
||||
<div class="row">
|
||||
<div class="col-sm-2 col-xs-3">
|
||||
<div class="round-image-container">
|
||||
<i class="mdi mdi-file-export" title="{'Export'|t}"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-10 col-xs-9">
|
||||
<div class="list-item-label">{'Export'|t}</div>
|
||||
<div class="list-item-sublabel">{'Export Netscape html bookmarks (which can be imported in Firefox, Chrome, Opera, delicious...)'|t}</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{if="!empty($linkcount)"}
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<hr class="darker"/>
|
||||
<h2 class="mtm">{'Statistics'|t}</h2>
|
||||
<ul>
|
||||
<li><strong>{$linkcount}</strong> links in total</li>
|
||||
<li><strong>{$privateLinkcount}</strong> private links</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{if="isset($tools_plugin)"}
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<hr class="darker"/>
|
||||
<h2 class="mtm">Plugin settings</h2>
|
||||
{loop="$tools_plugin"}
|
||||
{$value}
|
||||
{/loop}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<hr class="darker"/>
|
||||
<h2 class="mtm">Bookmarklet</h2>
|
||||
<p>You can easily bookmark links from anywhere on the web via bookmarklets right below.</p>
|
||||
<p>They can be dragged and dropped among your browser's bookmarks. Then, you just have to click on them from your bookmarks menu.</p>
|
||||
<div class="row">
|
||||
<div class="col-xs-6 text-center">
|
||||
<a class="bookmarklet"
|
||||
href="javascript:(
|
||||
function(){
|
||||
var%20url%20=%20location.href;
|
||||
var%20title%20=%20document.title%20||%20url;
|
||||
var%20desc=document.getSelection().toString();
|
||||
if(desc.length>4000){
|
||||
desc=desc.substr(0,4000)+'...';
|
||||
alert('{function="str_replace(' ', '%20', t('The selected text is too long, it will be truncated.'))"}');
|
||||
}
|
||||
window.open(
|
||||
'{$pageabsaddr}admin/shaare?post='%20+%20encodeURIComponent(url)+
|
||||
'&title='%20+%20encodeURIComponent(title)+
|
||||
'&description='%20+%20encodeURIComponent(desc)+
|
||||
'&source=bookmarklet','_blank','menubar=no,height=800,width=600,toolbar=no,scrollbars=yes,status=no,dialog=1'
|
||||
);
|
||||
}
|
||||
)();">
|
||||
<img src="{$asset_path}/dist/img/tools/star-circle.png#" alt="" /> {'Shaare link'|t}
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-xs-6 text-center">
|
||||
<a class="bookmarklet"
|
||||
href="javascript:(
|
||||
function(){
|
||||
var%20desc=document.getSelection().toString();
|
||||
if(desc.length>4000){
|
||||
desc=desc.substr(0,4000)+'...';
|
||||
alert('{function="str_replace(' ', '%20', t('The selected text is too long, it will be truncated.'))"}');
|
||||
}
|
||||
window.open(
|
||||
'{$pageabsaddr}?private=1&post='+
|
||||
'&description='%20+%20encodeURIComponent(desc)+
|
||||
'&source=bookmarklet','_blank','menubar=no,height=800,width=600,toolbar=no,scrollbars=yes,status=no,dialog=1'
|
||||
);
|
||||
}
|
||||
)();">
|
||||
<img src="{$asset_path}/dist/img/tools/star-circle.png#" alt="" /> {'Add Note'|t}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mbm">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<hr class="darker"/>
|
||||
<h2 class="mtm" id="firefox-api-title">{'3rd party'|t}</h2>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://addons.mozilla.org/fr/firefox/addon/shaarli/" title="Firefox {'Plugin'|t}" class="large-icon-button ripple">
|
||||
<i class="mdi mdi-firefox"></i>
|
||||
Firefox {'plugin'|t}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://chromewebstore.google.com/detail/add-to-shaarli/jhfblapoehcfajokolimghdfmeeakbee" title="Chrome {'Plugin'|t}" class="large-icon-button ripple">
|
||||
<i class="mdi mdi-google-chrome"></i>
|
||||
Chrome {'plugin'|t}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://f-droid.org/fr/packages/com.dimtion.shaarlier/" title="Android Shaarlier" class="large-icon-button ripple">
|
||||
<i class="mdi mdi-android"></i>
|
||||
Shaarlier
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://stakali.toneiv.eu/" title="Android Stakali" class="large-icon-button ripple">
|
||||
<i class="mdi mdi-android"></i>
|
||||
Stakali
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://github.com/lockcp/ShaarliOS" class="large-icon-button ripple">
|
||||
<i class="mdi mdi-apple-ios"></i>
|
||||
iOS
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<p>Other <a href="https://shaarli.readthedocs.io/en/master/Community-and-related-software.html">{'Community and related software'|t}</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{loop="$tools_plugin"}
|
||||
{$value}
|
||||
{/loop}
|
||||
</div>
|
||||
{include="page.footer"}
|
||||
</body>
|
||||
</html>
|
||||
6131
example_Shaarli-Material/package-lock.json
generated
Normal file
54
example_Shaarli-Material/package.json
Normal file
@ -0,0 +1,54 @@
|
||||
{
|
||||
"name": "shaarlimaterial",
|
||||
"version": "0.14.0",
|
||||
"description": "Shaarli Material is a theme for [Shaarli](https://github.com/shaarli/Shaarli), the personal, minimalist, super fast, database-free, bookmarking service.",
|
||||
"main": "src/js/main.js",
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"autosize": "^6.0.1",
|
||||
"awesomplete": "^1.1.5",
|
||||
"blazy": ">=1.3.0",
|
||||
"bootstrap": "^3.4.1",
|
||||
"jquery": "^3.5.1",
|
||||
"qrcode": "^1.4.4",
|
||||
"salvattore": "^1.0.9",
|
||||
"sortablejs": "^1.13.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-commonjs": "^28.0.2",
|
||||
"@rollup/plugin-eslint": "^9.0.3",
|
||||
"@rollup/plugin-node-resolve": "^16.0.0",
|
||||
"@rollup/plugin-terser": "^0.4.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"csso": "^5.0.5",
|
||||
"eslint": "^9.17.0",
|
||||
"neostandard": "^0.12.0",
|
||||
"postcss": "^8.2.4",
|
||||
"postcss-clean": "^1.1.0",
|
||||
"rollup": "^4.29.1",
|
||||
"rollup-plugin-copy": "^3.3.0",
|
||||
"rollup-plugin-css-only": "^4.3.0",
|
||||
"rollup-plugin-sass": "^1.12.19",
|
||||
"sass": "^1.32.4"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "cross-env NODE_ENV=production rollup -c --strictDeprecations",
|
||||
"dev": "cross-env NODE_ENV=development rollup -c --watch",
|
||||
"lint": "eslint src/js",
|
||||
"lint:fix": "eslint src/js --fix"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/kalvn/Shaarli-Material.git"
|
||||
},
|
||||
"keywords": [
|
||||
"shaarli",
|
||||
"material",
|
||||
"design"
|
||||
],
|
||||
"author": "kalvn",
|
||||
"license": "MIT",
|
||||
"browserslist": [
|
||||
"last 5 versions"
|
||||
]
|
||||
}
|
||||
50
example_Shaarli-Material/rollup.config.js
Normal file
@ -0,0 +1,50 @@
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
|
||||
import resolve from '@rollup/plugin-node-resolve';
|
||||
import commonjs from '@rollup/plugin-commonjs';
|
||||
import postcss from 'postcss';
|
||||
import clean from 'postcss-clean';
|
||||
import copy from 'rollup-plugin-copy';
|
||||
import terser from '@rollup/plugin-terser';
|
||||
import sass from 'rollup-plugin-sass';
|
||||
import css from 'rollup-plugin-css-only';
|
||||
import { minify } from 'csso';
|
||||
|
||||
const config = {
|
||||
input: 'src/js/main.js',
|
||||
output: {
|
||||
file: 'material/dist/bundle.js',
|
||||
format: 'iife'
|
||||
},
|
||||
plugins: [
|
||||
resolve({
|
||||
browser: true
|
||||
}),
|
||||
commonjs(),
|
||||
css({
|
||||
output: function (styles) {
|
||||
fs.writeFileSync(path.join('material', 'dist', 'lib.css'), minify(styles).css);
|
||||
}
|
||||
}),
|
||||
sass({
|
||||
output: true,
|
||||
processor: css => postcss([clean])
|
||||
.process(css, { from: undefined })
|
||||
.then(result => result.css)
|
||||
}),
|
||||
process.env.NODE_ENV === 'production' ? terser() : null,
|
||||
copy({
|
||||
targets: [
|
||||
{ src: 'src/assets/fonts', dest: 'material/dist' },
|
||||
{ src: 'src/assets/img', dest: 'material/dist' },
|
||||
{ src: 'node_modules/bootstrap/dist/fonts/*', dest: 'material/dist/fonts' }
|
||||
]
|
||||
})
|
||||
],
|
||||
watch: {
|
||||
exclude: 'node_modules/**'
|
||||
}
|
||||
};
|
||||
|
||||
export default config;
|
||||
BIN
example_Shaarli-Material/screenshots/configuration.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
example_Shaarli-Material/screenshots/home.png
Normal file
|
After Width: | Height: | Size: 71 KiB |
BIN
example_Shaarli-Material/screenshots/settings.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
example_Shaarli-Material/screenshots/showcase.png
Normal file
|
After Width: | Height: | Size: 148 KiB |
|
After Width: | Height: | Size: 2.0 MiB |
@ -0,0 +1,203 @@
|
||||
Font data copyright Google 2012
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
BIN
example_Shaarli-Material/src/assets/fonts/roboto/Roboto-Bold.ttf
Normal file
BIN
example_Shaarli-Material/src/assets/fonts/roboto/Roboto-Thin.ttf
Normal file
BIN
example_Shaarli-Material/src/assets/img/arrow-compress.png
Normal file
|
After Width: | Height: | Size: 300 B |
BIN
example_Shaarli-Material/src/assets/img/arrow-expand.png
Normal file
|
After Width: | Height: | Size: 298 B |
|
After Width: | Height: | Size: 564 B |
|
After Width: | Height: | Size: 638 B |
|
After Width: | Height: | Size: 904 B |
|
After Width: | Height: | Size: 978 B |
|
After Width: | Height: | Size: 679 B |
|
After Width: | Height: | Size: 728 B |
|
After Width: | Height: | Size: 852 B |
|
After Width: | Height: | Size: 916 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 916 B |
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<browserconfig>
|
||||
<msapplication>
|
||||
<tile>
|
||||
<square70x70logo src="tpl/material/images/favicons/mstile-70x70.png"/>
|
||||
<square150x150logo src="tpl/material/images/favicons/mstile-150x150.png"/>
|
||||
<wide310x150logo src="tpl/material/images/favicons/mstile-310x150.png"/>
|
||||
<TileColor>#603cba</TileColor>
|
||||
</tile>
|
||||
</msapplication>
|
||||
</browserconfig>
|
||||
|
After Width: | Height: | Size: 341 B |
|
After Width: | Height: | Size: 536 B |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 978 B |
BIN
example_Shaarli-Material/src/assets/img/favicons/favicon.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "Links",
|
||||
"icons": [
|
||||
{
|
||||
"src": "tpl\/material\/images\/favicons\/android-chrome-36x36.png",
|
||||
"sizes": "36x36",
|
||||
"type": "image\/png",
|
||||
"density": "0.75"
|
||||
},
|
||||
{
|
||||
"src": "tpl\/material\/images\/favicons\/android-chrome-48x48.png",
|
||||
"sizes": "48x48",
|
||||
"type": "image\/png",
|
||||
"density": "1.0"
|
||||
},
|
||||
{
|
||||
"src": "tpl\/material\/images\/favicons\/android-chrome-72x72.png",
|
||||
"sizes": "72x72",
|
||||
"type": "image\/png",
|
||||
"density": "1.5"
|
||||
},
|
||||
{
|
||||
"src": "tpl\/material\/images\/favicons\/android-chrome-96x96.png",
|
||||
"sizes": "96x96",
|
||||
"type": "image\/png",
|
||||
"density": "2.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
After Width: | Height: | Size: 959 B |
|
After Width: | Height: | Size: 990 B |
|
After Width: | Height: | Size: 1.1 KiB |
BIN
example_Shaarli-Material/src/assets/img/sad_star.png
Normal file
|
After Width: | Height: | Size: 6.9 KiB |
BIN
example_Shaarli-Material/src/assets/img/tools/star-circle.png
Normal file
|
After Width: | Height: | Size: 658 B |
46
example_Shaarli-Material/src/js/components/action-bar.js
Normal file
@ -0,0 +1,46 @@
|
||||
import $ from 'jquery';
|
||||
|
||||
import animations from './animations';
|
||||
import { guid } from './utils';
|
||||
|
||||
const displayActionBar = function (options) {
|
||||
if (typeof options !== 'object') {
|
||||
console.error('displayActionBar expects an object as options.');
|
||||
return;
|
||||
}
|
||||
|
||||
const uid = guid();
|
||||
let html = '<div id="' + uid + '" class="hidden actionbar ' + options.classes + '"><div class="container"><div class="row"><div class="actionbar-label">' + options.label + '</div><div class="actionbar-selectall">- <a href="#" class="actionbar-selectall-link">select all</a></div><div class="actionbar-controls">';
|
||||
|
||||
if (options.displayCancel) {
|
||||
html += '<button type="button" class="button button-default" id="actionbar-cancel">Cancel</button>';
|
||||
}
|
||||
|
||||
for (const i in options.controls) {
|
||||
const control = options.controls[i];
|
||||
html += '<button type="button" class="' + control.classes + '" id="' + control.id + '">' + control.label + '</button>';
|
||||
}
|
||||
|
||||
html += '</div></div></div></div>';
|
||||
|
||||
$('body').append(html);
|
||||
|
||||
const $actionbar = $('#' + uid).eq(0);
|
||||
|
||||
if (typeof options.onCancel === 'function') {
|
||||
$('#actionbar-cancel').on('click', function () {
|
||||
options.onCancel();
|
||||
});
|
||||
}
|
||||
|
||||
for (const i in options.controls) {
|
||||
const control = options.controls[i];
|
||||
$('#' + control.id).on('click', control.callback);
|
||||
}
|
||||
|
||||
animations.showSlideFromBottom($actionbar);
|
||||
|
||||
return $actionbar;
|
||||
};
|
||||
|
||||
export default displayActionBar;
|
||||
97
example_Shaarli-Material/src/js/components/animations.js
Normal file
@ -0,0 +1,97 @@
|
||||
import $ from 'jquery';
|
||||
|
||||
const animationEventName = 'animationend';
|
||||
|
||||
const animations = {
|
||||
animation: function (animationName, element, callbackBegin, callbackEnd) {
|
||||
element.on(animationEventName + '.' + animationName, function () {
|
||||
// Removes this listener and animation classes.
|
||||
$(this).off(animationEventName + '.' + animationName)
|
||||
.removeClass(function (index, classes) {
|
||||
return (classes.match(/animate-\S+/g) || []).join(' ');
|
||||
});
|
||||
|
||||
// Calls the specified callback if it exists.
|
||||
if (typeof callbackEnd === 'function') {
|
||||
callbackEnd();
|
||||
}
|
||||
});
|
||||
|
||||
element.addClass('animate-' + animationName);
|
||||
if (typeof callbackBegin === 'function') {
|
||||
callbackBegin();
|
||||
}
|
||||
},
|
||||
fadeIn: function (element, callbackBegin, callbackEnd) {
|
||||
const realCallbackBegin = function () {
|
||||
element.removeClass('hidden');
|
||||
if (typeof callbackBegin === 'function') {
|
||||
callbackBegin();
|
||||
}
|
||||
};
|
||||
|
||||
this.animation('fade-in', element, realCallbackBegin, callbackEnd);
|
||||
},
|
||||
fadeOut: function (element, callbackBegin, callbackEnd) {
|
||||
const realCallbackEnd = function () {
|
||||
element.addClass('hidden');
|
||||
if (typeof callbackEnd === 'function') {
|
||||
callbackEnd();
|
||||
}
|
||||
};
|
||||
|
||||
this.animation('fade-out', element, callbackBegin, realCallbackEnd);
|
||||
},
|
||||
slideFromTop: function (element, callbackBegin, callbackEnd) {
|
||||
const realCallbackBegin = function () {
|
||||
element.removeClass('hidden');
|
||||
if (typeof callbackBegin === 'function') {
|
||||
callbackBegin();
|
||||
}
|
||||
};
|
||||
|
||||
this.animation('slide-from-top', element, realCallbackBegin, callbackEnd);
|
||||
},
|
||||
slideFromRight: function (element, callbackBegin, callbackEnd) {
|
||||
const realCallbackBegin = function () {
|
||||
element.removeClass('hidden');
|
||||
if (typeof callbackBegin === 'function') {
|
||||
callbackBegin();
|
||||
}
|
||||
};
|
||||
|
||||
this.animation('slide-from-right', element, realCallbackBegin, callbackEnd);
|
||||
},
|
||||
hideSlideToBottom: function (element, callbackBegin, callbackEnd) {
|
||||
const realCallbackEnd = function () {
|
||||
element.addClass('hidden');
|
||||
if (typeof callbackEnd === 'function') {
|
||||
callbackEnd();
|
||||
}
|
||||
};
|
||||
|
||||
this.animation('hide-slide-to-bottom', element, callbackBegin, realCallbackEnd);
|
||||
},
|
||||
showSlideFromBottom: function (element, callbackBegin, callbackEnd) {
|
||||
const realCallbackBegin = function () {
|
||||
element.removeClass('hidden');
|
||||
if (typeof callbackBegin === 'function') {
|
||||
callbackBegin();
|
||||
}
|
||||
};
|
||||
|
||||
this.animation('show-slide-from-bottom', element, realCallbackBegin, callbackEnd);
|
||||
},
|
||||
compressHeight: function (element, callbackBegin, callbackEnd) {
|
||||
const realCallbackEnd = function () {
|
||||
element.addClass('hidden');
|
||||
if (typeof callbackEnd === 'function') {
|
||||
callbackEnd();
|
||||
}
|
||||
};
|
||||
|
||||
this.animation('compress-height-50', element, callbackBegin, realCallbackEnd);
|
||||
}
|
||||
};
|
||||
|
||||
export default animations;
|
||||
159
example_Shaarli-Material/src/js/components/batch-add.js
Normal file
@ -0,0 +1,159 @@
|
||||
import $ from 'jquery';
|
||||
|
||||
import http from './http';
|
||||
import modal from './modal';
|
||||
|
||||
const saveLink = async function ($form) {
|
||||
const data = {};
|
||||
const exists = $form.find('[name="lf_id"]').length > 0;
|
||||
|
||||
$form.find('input[type="text"], textarea, input[type="checkbox"], input[type="hidden"]')
|
||||
.each(function (index, element) {
|
||||
const $element = $(element);
|
||||
if ($element.attr('type') === 'checkbox') {
|
||||
if ($element.prop('checked')) {
|
||||
data[$element.attr('name')] = 'on';
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
data[$element.attr('name')] = $element.val();
|
||||
});
|
||||
|
||||
try {
|
||||
formBeforeLoad($form);
|
||||
|
||||
await http.createLink(data);
|
||||
|
||||
formAfterLoad($form, exists ? 'updated' : 'created', 'success');
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
formError($form);
|
||||
modal('Error', 'Something went wrong when saving the link.', 'alert');
|
||||
}
|
||||
};
|
||||
|
||||
const saveAllLinks = async function () {
|
||||
const forms = document.querySelectorAll('form[name="linkform"]');
|
||||
const total = forms.length;
|
||||
const $progressOverlay = $('#progress-overlay');
|
||||
const $progressCurrent = $progressOverlay.find('.progress-current');
|
||||
const $progressTotal = $progressOverlay.find('.progress-total');
|
||||
const $progressActual = $progressOverlay.find('.progress-actual');
|
||||
|
||||
$progressTotal.text(total);
|
||||
|
||||
$progressOverlay.removeClass('hidden');
|
||||
|
||||
for (let i = 0; i < total; i++) {
|
||||
await saveLink($(forms[i]));
|
||||
$progressCurrent.text(i + 1);
|
||||
$progressActual.css('width', `${(i + 1) * 100 / total}%`);
|
||||
}
|
||||
|
||||
$progressOverlay.addClass('hidden');
|
||||
};
|
||||
|
||||
const deleteLink = async function ($buttonDelete) {
|
||||
const url = $buttonDelete.attr('href');
|
||||
const $form = $buttonDelete.closest('form');
|
||||
|
||||
modal('Delete link', 'Are you sure you want to delete this link?', 'confirm', async function (accepts) {
|
||||
if (accepts) {
|
||||
try {
|
||||
formBeforeLoad($form);
|
||||
|
||||
await http.deleteLinkByUrl(url);
|
||||
|
||||
formAfterLoad($form, 'deleted', 'danger');
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
formError($form);
|
||||
modal('Error', 'Something went wrong when deleting the link.', 'alert');
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const cancelLink = async function ($buttonCancel) {
|
||||
const $form = $buttonCancel.closest('form');
|
||||
|
||||
formBeforeLoad($form);
|
||||
|
||||
// Necessary for the animation to play properly.
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
|
||||
formAfterLoad($form, 'cancelled');
|
||||
};
|
||||
|
||||
// Checks if there are remaining links.
|
||||
const noMoreLinks = function () {
|
||||
if ($('form[name="linkform"]').length === 0) {
|
||||
$('[name="save_edit_batch"]').attr('disabled', 'disabled');
|
||||
}
|
||||
};
|
||||
|
||||
const formBeforeLoad = function ($form) {
|
||||
$form.append('<div class="card-overlay"></div>');
|
||||
const height = $form.height();
|
||||
$form.css('max-height', `${height}px`);
|
||||
};
|
||||
const formAfterLoad = function ($form, message, type) {
|
||||
const url = $form.find('[name="lf_url"]').val();
|
||||
const customClass = type ? `is-${type}` : '';
|
||||
$form.find('.card-overlay').html(`<div class="is-flex"><div class="nowrap">${url}</div><div class="tag is-light ${customClass}">${message}</div></div>`);
|
||||
$form.closest('.editlinkform').addClass('is-batch-done');
|
||||
// Prevents this form from being treated again.
|
||||
$form.removeAttr('name');
|
||||
};
|
||||
const formError = function ($form) {
|
||||
$form.find('.card-overlay').remove();
|
||||
$form.css('max-height', 'none');
|
||||
};
|
||||
|
||||
const batchAdd = {
|
||||
init: function () {
|
||||
if (shaarli.pageName === 'addlink') {
|
||||
$('.button-batch-addform').on('click', function () {
|
||||
$('.batch-addform').removeClass('hidden');
|
||||
$(this).remove();
|
||||
});
|
||||
}
|
||||
|
||||
if (shaarli.pageName === 'editlinkbatch') {
|
||||
// Single save buttons.
|
||||
$('[name="save_edit"]').on('click', async function (event) {
|
||||
event.preventDefault();
|
||||
await saveLink($(this).closest('form'));
|
||||
noMoreLinks();
|
||||
return false;
|
||||
});
|
||||
|
||||
$('[name="save_edit_batch"]').on('click', async function (event) {
|
||||
event.preventDefault();
|
||||
await saveAllLinks();
|
||||
noMoreLinks();
|
||||
return false;
|
||||
});
|
||||
|
||||
// Single delete buttons.
|
||||
$('[name="delete_link"]').off('click').on('click', async function (event) {
|
||||
event.preventDefault();
|
||||
await deleteLink($(this));
|
||||
noMoreLinks();
|
||||
return false;
|
||||
});
|
||||
|
||||
// Single cancel buttons.
|
||||
$('[name="cancel-batch-link"]').on('click', async function (event) {
|
||||
event.preventDefault();
|
||||
await cancelLink($(this));
|
||||
noMoreLinks();
|
||||
return false;
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default batchAdd;
|
||||