Compare commits

...

112 Commits

Author SHA1 Message Date
Dan Brown
d485fcb3db Updated version and assets for release v23.05 2023-05-03 11:05:33 +01:00
Dan Brown
0f895668a4 Merge branch 'development' into release 2023-05-03 11:03:29 +01:00
Dan Brown
57bdd83d8c Added mostodon badge in readme, updated CLI 2023-05-03 10:57:09 +01:00
Dan Brown
ce0b75294f Set page include limit to be 3 as expected instead of 4 2023-05-02 12:44:55 +01:00
Dan Brown
4bb2b31bc9 Updated translator attribution pre v23.05 release 2023-05-01 19:39:20 +01:00
Dan Brown
9d74508ae3 Updated translations with latest Crowdin changes (#4163) 2023-05-01 19:37:49 +01:00
Dan Brown
c41baa1b76 Updated CLI & PHP deps, added gitignore for local composer 2023-05-01 18:44:46 +01:00
Dan Brown
cd32597d4d Fixed broken favourites in code editor 2023-05-01 18:43:03 +01:00
Dan Brown
8594656f6e Merge pull request #4206 from BookStackApp/system_cli
Added System CLI
2023-04-28 19:17:38 +01:00
Dan Brown
0aca1c2332 Added system cli, and created backups directory 2023-04-28 19:08:45 +01:00
Dan Brown
8c738aedee Added sessionindex to SAML2 single logout request to idp
related to  #3936
2023-04-28 13:55:25 +01:00
Dan Brown
f64ce71afc Added oidc_id_token_pre_validate logical theme event
For #4200
2023-04-27 23:40:14 +01:00
Dan Brown
277d5392fb Merge branch 'esakkiraja100116/development' into development 2023-04-27 16:34:14 +01:00
Dan Brown
23c35af9ef Review of #4202, Rolled out to other searches, added testing 2023-04-27 16:33:24 +01:00
esakkiraja100116
78fecdfcb0 suggesstion issue fix (#4175) 2023-04-27 16:32:39 +01:00
SnowCode
a9d952560d Adding a video { width: 100%; } (#4204)
* Adding a video { width: 100%; }

This is to prevent that videos included in pages don't exceed the page border

* Reverting precedent commit

* Adding a video { max-width: 100% } instead
2023-04-27 15:58:35 +01:00
Dan Brown
56f234d1ee Review of #4192, Fixed formatting and added test 2023-04-27 15:52:16 +01:00
jasonF1000
011800d425 changed PageContent.php to accept nested includes (#4192)
* changed app/Entities/Tools/PageContent.php to accept nested include levels. Tested it and it works.

* changed recommendations

This loop is now only around parsePageIncludes and bugfixes the space indentation.

* Update PageContent.php

fix spaces
2023-04-27 15:51:46 +01:00
Dan Brown
647ce6c237 Fixed sort urls with no params not building full path
The provided partial path would be return which may not resolve to the
full URL when used on systems like those hosting BookStack on a
sub-path.
Fixes #4201
2023-04-27 13:49:22 +01:00
Dan Brown
607da73109 Merge pull request #4193 from BookStackApp/custom_dropzone
Custom dropzone implementation
2023-04-27 13:43:38 +01:00
Dan Brown
1135d477ba Fixed linting and failing test issues from dropzone work 2023-04-27 13:31:03 +01:00
Dan Brown
a4a96a3df7 Dropzone: Adjusted styles for dark mode 2023-04-27 12:55:05 +01:00
Dan Brown
38e8a96dcd Removed dropzone from package and attribution list 2023-04-26 23:35:25 +01:00
Dan Brown
9a17656f88 dropzone: Addressed existing todos, cleaned attachment ux
Updated dom layout of attahcments to prevent nested dropzones (No issue
but potential to be one) and updated edit form dropzone handling so the
dropzone item card was not as distracting.
2023-04-26 23:31:38 +01:00
Dan Brown
e36cdaad0d Updated attachments to work with new dropzone
- Fixes existing broken attachment edit tabs.
- Redesigns area to move away from old tabbed interface.
- Integrates new dropzone system, for both addition and edit.
2023-04-26 16:41:34 +01:00
Dan Brown
722c38d576 Image manager: fix upload control for drawing, updated styles
- Tightened image manager styles to address things that looked akward.
- Prevented visiblity/use of upload controls for drawings.
- Updated dropzone to use error handling from validation messages.
2023-04-26 14:25:56 +01:00
Dan Brown
8cd6c797e8 Merge branch 'development' of github.com:BookStackApp/BookStack into development 2023-04-26 01:43:16 +01:00
Dan Brown
dff45e2c5d Fixed broken shortcut hint overlay
Also updated event handler usage to use abort controller while there.
2023-04-26 01:42:12 +01:00
Dan Brown
61d2ea6ac7 Dropzone: Polished image manager elements
- Added file placeholder for non-image uploads.
- Added use of upload limits.
- Removed upload timeout variable.
- Added pass-through and usage of filetypes.
- Extracted some view text to language files and made use of existing
  text.
2023-04-25 16:41:39 +01:00
Esakkiraja
752562d23d .vscode folder is added in .gitignore file (#4197)
Squash of 7 commits.

---------

Co-authored-by: esakkiraja100116 <esakkiraja100116@gmai.com>
2023-04-25 15:25:31 +01:00
Dan Brown
b21a9007c5 Dropzone: Developed ux further
- Added image manager button for uploads.
- Added image manager placeholder sidebar text for guidance.
- Improved dropzone layer styling.
- Removed old dropzone styles.
- Got success events and auto-hide working.
- Updated upload items to animate out.
2023-04-25 13:10:25 +01:00
Dan Brown
a8fc29a31e Dropzone: started on design/ui of uploading
- Added new wider target handling.
- Updated upload item dom with design and seperate "landing" zone.
- Added new helper for simple dom element creation.
2023-04-24 23:24:58 +01:00
Dan Brown
36116a45d4 Dropzone: Swapped fetch for XHR for progress tracking 2023-04-24 18:18:08 +01:00
Dan Brown
23915c3b1a Started custom dropzone implementation 2023-04-24 16:19:20 +01:00
Dan Brown
55af22b487 Merge pull request #4191 from tigsikram/fix-api-docs-timestamp
Fix timestamp in API docs example response
2023-04-24 14:46:40 +01:00
Mark Weiler
01f3f4d315 Fix timestamp in API docs example response 2023-04-24 11:19:00 +02:00
Dan Brown
58cadce052 Merge branch 'feature/mail-verify-peer' into development 2023-04-23 15:05:13 +01:00
Dan Brown
1de72d09ca Mail: updated peer verify option name and added test 2023-04-23 15:04:35 +01:00
Dan Brown
fa6fcc1c1c Added clojure code language option
For #4112
2023-04-23 14:16:31 +01:00
Dan Brown
a46b438a4c Merge branch 'wkhtmltopdf-env-example' into development 2023-04-21 11:56:31 +01:00
Dan Brown
7505443a0c Updated complete env wkhtml text and added advisory
Added advisory to start to refer to docs for full details.
Updated added WKHTMLTOPDF option text.
2023-04-21 11:54:23 +01:00
Dan Brown
f837083c12 Updated php deps 2023-04-21 11:37:41 +01:00
Dan Brown
e1bd13f481 Edits from reviewing public events page 2023-04-20 16:54:11 +01:00
Dan Brown
c74f7cc628 Documented public JS events used
Related to #4179
2023-04-20 16:25:48 +01:00
Dan Brown
9f467f4052 Merge pull request #4181 from BookStackApp/js_formatting
Added standard JS formatting via ESLint
2023-04-19 23:01:10 +01:00
Dan Brown
974390688d ESLINT: Added GH action and details to dev docs 2023-04-19 22:56:55 +01:00
Dan Brown
da3ae3ba8b ESLINT: Addressed remaining detected issues 2023-04-19 15:20:04 +01:00
Dan Brown
0519e58fbf ESLINT: Started inital pass at addressing issues 2023-04-19 10:46:13 +01:00
Dan Brown
e711290d8b Ran eslint fix on existing codebase
Had to do some manual fixing of the app.js file due to misplaced
comments
2023-04-18 22:20:02 +01:00
Dan Brown
752ee664c2 Added code formatting standard via eslint 2023-04-18 22:19:27 +01:00
Dan Brown
69d03042c6 Merge pull request #3617 from BookStackApp/codemirror6
Upgrade to codemirror 6
2023-04-18 15:35:39 +01:00
Dan Brown
baf5edd73a CM6: Further fixes/improvements after testing
- Updated event naming to be "cm6" when codemirror-specific.
- Removed cm block border in md editor to prevent double bordering.
- Updated copy handling to fallback to execCommand.
2023-04-18 15:08:17 +01:00
Dan Brown
3e738b1471 CM6: Fixed a range of issues during browser testing
- Fixed some keybindings not running as expected, due to some editor
  defaults overriding or further actions taking place since the action
  would not indicate it's been dealt with (by returning boolean).
- Fixed spacing/border-radius being used on codeblocks on non-intended
  areas like the MD editor.
- Fixed lack of BG on default light theme, visible on full screen md
  editor.
- Fixed error thrown when the user does not have access to change the
  current editor (Likely non-cm related existing issue)
2023-04-18 14:21:22 +01:00
Dan Brown
94f464cd14 CM6: Added tabbing, fixed dark mode border in WYSIWYG 2023-04-18 13:43:59 +01:00
Dan Brown
900571ac9c CM6: Updated for popup editor, added new interface
New simple interface added for abstraction of CM editor in simple
use-cases, just to provide common actions like get/set content, focus
and set mode.
2023-04-17 13:24:29 +01:00
Dan Brown
09fd0bc5b7 CM6: Got WYSIWYG code blocks working
Required monkey-patch to work around potential codemirror issue with
shadowdom+iframe usage.
Also updated JS packages to latest versions.
2023-04-16 23:50:11 +01:00
Dan Brown
74b4751a1c CM6: Aligned styling with existing, improved theme handling 2023-04-16 16:05:16 +01:00
Dan Brown
74b76ecdb9 Updated cm6 theme handling to allow extension via API
Uses our custom event system, uses methods that take callables so that
internal dependancies can be passed.
2023-04-15 15:35:41 +01:00
Dan Brown
9874a53206 Added cm6 strategy for splitting and dyn. loading langs
Split out legacy modes to their own dynamically imported bundle to
reduce main code bundle size.
2023-04-14 18:08:57 +01:00
Dan Brown
257a703878 Addressed existing cm6 todos
- Updated clipboard handling
  - Removed old clipboard package for browser-native API.
- Updated codemirror editor events to use new props for new data types.
2023-04-14 14:08:40 +01:00
Dan Brown
fdda813d5f Cleaned up change handling in cm6 editor action handling 2023-04-13 17:38:11 +01:00
Dan Brown
6f45d34bf8 Finished update pass of all md editor actions to cm6 2023-04-13 17:18:32 +01:00
Dan Brown
32c765d0c3 Updated another range of actions for cm6 2023-04-13 12:51:52 +01:00
Dan Brown
9813c94720 Made a start on updating editor actions 2023-04-11 13:16:04 +01:00
Dan Brown
da3e4f5f75 Got md shortcuts working, marked actions for update 2023-04-11 11:48:58 +01:00
Dan Brown
572037ef1f Got markdown editor barely functional
Updated content sync and preview scoll sync to work.
Many features commented out until they can be updated.
2023-04-10 15:01:44 +01:00
Dan Brown
50f3c10f19 Merge branch 'v23.02-branch' into development 2023-04-07 18:12:00 +01:00
Dan Brown
6c577ac3bf Updated version and assets for release v23.02.3 2023-04-07 18:07:32 +01:00
Dan Brown
31cc2423d2 Merge branch 'v23.02-branch' into release 2023-04-07 18:07:09 +01:00
Dan Brown
3f3f221e0d Updated translator attribution before release v23.02.3 2023-04-07 18:06:44 +01:00
Dan Brown
d0f970fe4f Updated translations with latest Crowdin changes (#4131) 2023-04-07 18:00:03 +01:00
Dan Brown
95b75c067f Updated translations with latest Crowdin changes (#4131) 2023-04-07 17:59:34 +01:00
Dan Brown
81134e7071 Fixed tag numbering in last commit 2023-04-07 17:54:17 +01:00
Dan Brown
e722ee4268 Fixed click issue with tag suggestions in safari
Updated selectable elements to be divs instead of buttons since Safari
akwardly does not focus on buttons on click.
Also standardised keyboard handling to our standard nav class.
Also addressed empty tag values showing in results.
For #4139
2023-04-07 17:50:57 +01:00
Dan Brown
fd674d10e3 Fixed error upon user delete with no migration id
Fixes #4162
2023-04-07 15:57:21 +01:00
Dan Brown
4835a0dcb1 Cleaned up old token services 2023-04-04 10:44:38 +01:00
Daiki Urata
d353e87ca1 Add WKHTMLTOPDF to .env.example.complete 2023-03-30 17:58:17 +09:00
Dan Brown
8e64324d62 Merge branch 'v23.02-branch' into development 2023-03-25 12:33:59 +00:00
Dan Brown
c9ed32e518 Updated version and assets for release v23.02.2 2023-03-25 12:27:32 +00:00
Dan Brown
6b4c3a0969 Merge branch 'v23.02-branch' into release 2023-03-25 12:27:05 +00:00
Dan Brown
0a0fdd7f3e Fixed delete role failing with no migrate role provided
For #4128
2023-03-25 12:21:22 +00:00
Dan Brown
3410cf21cb Updated php deps 2023-03-25 12:21:04 +00:00
Dan Brown
6e284d7a6c Fixed issue with user delete ownership not migrating
Caused by input not being part of the submitted form.
Updated test to ensure the input is within a form.
For #4124
2023-03-25 12:20:49 +00:00
Dan Brown
ea7914422c Updated php deps 2023-03-25 12:20:13 +00:00
Dan Brown
509cab3e28 Merged latest crowdin changes 2023-03-25 12:18:45 +00:00
Dan Brown
dde38e91b5 Fixed delete role failing with no migrate role provided
For #4128
2023-03-25 12:08:45 +00:00
Dan Brown
970088a8a1 Updated php deps 2023-03-24 14:46:30 +00:00
Dan Brown
0e43618dda Fixed issue with user delete ownership not migrating
Caused by input not being part of the submitted form.
Updated test to ensure the input is within a form.
For #4124
2023-03-24 14:43:48 +00:00
Vincent Bernat
f2293a70f8 Allow a user to disable peer check when using TLS/STARTTLS
This is useful when developing and on Docker setups. Despite setting
encryption to null, if a server supports STARTTLS with a self-signed
certificate, the mailer try to upgrade the connection with STARTTLS.
2023-03-24 09:34:37 +01:00
Dan Brown
dce5123452 Added own twig/smarty packages for cm6 lang support 2023-03-21 20:53:35 +00:00
Dan Brown
c81cb6f2af Merge branch 'development' into codemirror6 2023-03-19 10:22:44 +00:00
Dan Brown
9b66e93b15 Merge pull request #4103 from BookStackApp/image_api
Image API Endpoints
2023-03-15 11:45:36 +00:00
Dan Brown
402eb845ab Added examples, updated docs for image gallery api endpoints 2023-03-15 11:37:03 +00:00
Dan Brown
3a808fd768 Added phpunit tests to cover image API endpoints 2023-03-14 19:29:08 +00:00
Dan Brown
d9eec6d82c Started Image API build 2023-03-14 12:19:19 +00:00
Dan Brown
6357056d7b Updated php deps 2023-03-13 21:03:00 +00:00
Dan Brown
a369971e04 Merge pull request #4099 from BookStackApp/permissions_api
Content-Permissions API Endpoints
2023-03-13 20:55:44 +00:00
Dan Brown
1903924829 Added content-perms API examples and docs tweaks 2023-03-13 20:41:32 +00:00
Dan Brown
0de7530059 Tweaked content permission endpoints, covered with tests 2023-03-13 20:06:52 +00:00
Dan Brown
c42956bcaf Started build of content-permissions API endpoints 2023-03-13 13:18:33 +00:00
Dan Brown
7b5111571c Removed bookstack wording instances in color setting options 2023-02-28 01:01:25 +00:00
Dan Brown
2dad92d1bd Updated version and assets for release v23.02.1 2023-02-27 19:26:13 +00:00
Dan Brown
c1fb7ab7dc Merge branch 'development' into release 2023-02-27 19:23:33 +00:00
Dan Brown
3464f5e961 Updated translations with latest Crowdin changes (#4066) 2023-02-27 19:19:03 +00:00
Dan Brown
7c27d26161 Fixed language locale setting issue
Attempted to access an array that had been filtered and therefore could
have holes within, including as position 0 which would then be
accessed.
Also added cs language to internal map

Related to #4068
2023-02-27 19:14:45 +00:00
Dan Brown
c148e2f3d9 Added esbuild bundle inspection metafile 2023-02-17 22:37:13 +00:00
Dan Brown
f51036b203 Added newer languages where possible
Cannot find existing option for twig/smarty, need to look other methods.
2023-02-17 22:14:34 +00:00
Dan Brown
9135a85de4 Merge branch 'codemirror6' into codemirror6_take2 2023-02-17 21:28:23 +00:00
Dan Brown
9fd7a6abed Added dark theme handling 2022-08-04 14:19:04 +01:00
Dan Brown
4757ed9453 Converted codemirror languges to new packages where available
Does increase bundle size massively though, Will need to think about
solutions for this.
2022-08-04 13:33:51 +01:00
Dan Brown
97146a6359 Added handling of codemirror 6 code languages 2022-08-03 19:40:16 +01:00
Dan Brown
d4f2fcdf79 Started codemirror update, In broken state 2022-08-02 20:11:02 +01:00
415 changed files with 8960 additions and 6594 deletions

View File

@@ -3,6 +3,10 @@
# Each option is shown with it's default value.
# Do not copy this whole file to use as your '.env' file.
# The details here only serve as a quick reference.
# Please refer to the BookStack documentation for full details:
# https://www.bookstackapp.com/docs/
# Application environment
# Can be 'production', 'development', 'testing' or 'demo'
APP_ENV=production
@@ -79,6 +83,7 @@ MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_VERIFY_SSL=true
# Command to use when email is sent via sendmail
MAIL_SENDMAIL_COMMAND="/usr/sbin/sendmail -bs"
@@ -322,6 +327,13 @@ FILE_UPLOAD_SIZE_LIMIT=50
# Can be 'a4' or 'letter'.
EXPORT_PAGE_SIZE=a4
# Set path to wkhtmltopdf binary for PDF generation.
# Can be 'false' or a path path like: '/home/bins/wkhtmltopdf'
# When false, BookStack will attempt to find a wkhtmltopdf in the application
# root folder then fall back to the default dompdf renderer if no binary exists.
# Only used if 'ALLOW_UNTRUSTED_SERVER_FETCHING=true' which disables security protections.
WKHTMLTOPDF=false
# Allow <script> tags in page content
# Note, if set to 'true' the page editor may still escape scripts.
ALLOW_CONTENT_SCRIPTS=false
@@ -372,4 +384,4 @@ LOG_FAILED_LOGIN_CHANNEL=errorlog_plain_webserver
# IP address '146.191.42.4' would result in '146.191.x.x' being logged.
# For the IPv6 address '2001:db8:85a3:8d3:1319:8a2e:370:7348' this would result as:
# '2001:db8:85a3:8d3:x:x:x:x'
IP_ADDRESS_PRECISION=4
IP_ADDRESS_PRECISION=4

View File

@@ -311,3 +311,19 @@ m4tthi4s :: French
toras9000 :: Japanese
pathab :: German
MichelSchoon85 :: Dutch
Jøran Haugli (haugli92) :: Norwegian Bokmal
Vasileios Kouvelis (VasilisKouvelis) :: Greek
Dremski :: Bulgarian
Frédéric SENE (nothingfr) :: French
bendem :: French
kostasdizas :: Greek
Ricardo Schroeder (brownstone666) :: Portuguese, Brazilian
Eitan MG (EitanMG) :: Hebrew
Robin Flikkema (RobinFlikkema) :: Dutch
Michal Gurcik (mgurcik) :: Slovak
Pooyan Arab (pooyanarab) :: Persian
Ochi Darma Putra (troke12) :: Indonesian
H.-H. Peng (Hsins) :: Chinese Traditional
Mosi Wang (mosiwang) :: Chinese Traditional
骆言 (LawssssCat) :: Chinese Simplified
Stickers Gaming Shøw (StickerSGSHOW) :: French

16
.github/workflows/lint-js.yml vendored Normal file
View File

@@ -0,0 +1,16 @@
name: lint-js
on: [push, pull_request]
jobs:
build:
if: ${{ github.ref != 'refs/heads/l10n_development' }}
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v1
- name: Install NPM deps
run: npm ci
- name: Run formatting check
run: npm run lint

6
.gitignore vendored
View File

@@ -1,5 +1,7 @@
/vendor
/node_modules
/.vscode
/composer
Homestead.yaml
.env
.idea
@@ -21,8 +23,10 @@ yarn.lock
nbproject
.buildpath
.project
.nvmrc
.settings/
webpack-stats.json
.phpunit.result.cache
.DS_Store
phpstan.neon
phpstan.neon
esbuild-meta.json

View File

@@ -11,11 +11,9 @@ use Illuminate\Support\Facades\DB;
class TagRepo
{
protected PermissionApplicator $permissions;
public function __construct(PermissionApplicator $permissions)
{
$this->permissions = $permissions;
public function __construct(
protected PermissionApplicator $permissions
) {
}
/**
@@ -90,6 +88,7 @@ class TagRepo
{
$query = Tag::query()
->select('*', DB::raw('count(*) as count'))
->where('value', '!=', '')
->groupBy('value');
if ($searchTerm) {

View File

@@ -8,8 +8,8 @@ use BookStack\Notifications\ConfirmEmail;
class EmailConfirmationService extends UserTokenService
{
protected $tokenTable = 'email_confirmations';
protected $expiryTime = 24;
protected string $tokenTable = 'email_confirmations';
protected int $expiryTime = 24;
/**
* Create new confirmation for a user,

View File

@@ -4,35 +4,16 @@ namespace BookStack\Auth\Access\Oidc;
class OidcIdToken
{
/**
* @var array
*/
protected $header;
/**
* @var array
*/
protected $payload;
/**
* @var string
*/
protected $signature;
protected array $header;
protected array $payload;
protected string $signature;
protected string $issuer;
protected array $tokenParts = [];
/**
* @var array[]|string[]
*/
protected $keys;
/**
* @var string
*/
protected $issuer;
/**
* @var array
*/
protected $tokenParts = [];
protected array $keys;
public function __construct(string $token, string $issuer, array $keys)
{
@@ -106,6 +87,14 @@ class OidcIdToken
return $this->payload;
}
/**
* Replace the existing claim data of this token with that provided.
*/
public function replaceClaims(array $claims): void
{
$this->payload = $claims;
}
/**
* Validate the structure of the given token and ensure we have the required pieces.
* As per https://datatracker.ietf.org/doc/html/rfc7519#section-7.2.

View File

@@ -9,6 +9,8 @@ use BookStack\Auth\User;
use BookStack\Exceptions\JsonDebugException;
use BookStack\Exceptions\StoppedAuthenticationException;
use BookStack\Exceptions\UserRegistrationException;
use BookStack\Facades\Theme;
use BookStack\Theming\ThemeEvents;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Cache;
use League\OAuth2\Client\OptionProvider\HttpBasicAuthOptionProvider;
@@ -21,24 +23,12 @@ use Psr\Http\Client\ClientInterface as HttpClient;
*/
class OidcService
{
protected RegistrationService $registrationService;
protected LoginService $loginService;
protected HttpClient $httpClient;
protected GroupSyncService $groupService;
/**
* OpenIdService constructor.
*/
public function __construct(
RegistrationService $registrationService,
LoginService $loginService,
HttpClient $httpClient,
GroupSyncService $groupService
protected RegistrationService $registrationService,
protected LoginService $loginService,
protected HttpClient $httpClient,
protected GroupSyncService $groupService
) {
$this->registrationService = $registrationService;
$this->loginService = $loginService;
$this->httpClient = $httpClient;
$this->groupService = $groupService;
}
/**
@@ -226,6 +216,16 @@ class OidcService
$settings->keys,
);
$returnClaims = Theme::dispatch(ThemeEvents::OIDC_ID_TOKEN_PRE_VALIDATE, $idToken->getAllClaims(), [
'access_token' => $accessToken->getToken(),
'expires_in' => $accessToken->getExpires(),
'refresh_token' => $accessToken->getRefreshToken(),
]);
if (!is_null($returnClaims)) {
$idToken->replaceClaims($returnClaims);
}
if ($this->config()['dump_user_details']) {
throw new JsonDebugException($idToken->getAllClaims());
}

View File

@@ -67,7 +67,7 @@ class Saml2Service
$returnRoute,
[],
$user->email,
null,
session()->get('saml2_session_index'),
true,
Constants::NAMEID_EMAIL_ADDRESS
);
@@ -118,6 +118,7 @@ class Saml2Service
$attrs = $toolkit->getAttributes();
$id = $toolkit->getNameId();
session()->put('saml2_session_index', $toolkit->getSessionIndex());
return $this->processLoginCallback($id, $attrs);
}

View File

@@ -7,14 +7,12 @@ use BookStack\Notifications\UserInvite;
class UserInviteService extends UserTokenService
{
protected $tokenTable = 'user_invites';
protected $expiryTime = 336; // Two weeks
protected string $tokenTable = 'user_invites';
protected int $expiryTime = 336; // Two weeks
/**
* Send an invitation to a user to sign into BookStack
* Removes existing invitation tokens.
*
* @param User $user
*/
public function sendInvitation(User $user)
{

View File

@@ -14,41 +14,29 @@ class UserTokenService
{
/**
* Name of table where user tokens are stored.
*
* @var string
*/
protected $tokenTable = 'user_tokens';
protected string $tokenTable = 'user_tokens';
/**
* Token expiry time in hours.
*
* @var int
*/
protected $expiryTime = 24;
protected int $expiryTime = 24;
/**
* Delete all email confirmations that belong to a user.
*
* @param User $user
*
* @return mixed
* Delete all tokens that belong to a user.
*/
public function deleteByUser(User $user)
public function deleteByUser(User $user): void
{
return DB::table($this->tokenTable)
DB::table($this->tokenTable)
->where('user_id', '=', $user->id)
->delete();
}
/**
* Get the user id from a token, while check the token exists and has not expired.
*
* @param string $token
* Get the user id from a token, while checking the token exists and has not expired.
*
* @throws UserTokenNotFoundException
* @throws UserTokenExpiredException
*
* @return int
*/
public function checkTokenAndGetUserId(string $token): int
{
@@ -67,8 +55,6 @@ class UserTokenService
/**
* Creates a unique token within the email confirmation database.
*
* @return string
*/
protected function generateToken(): string
{
@@ -82,10 +68,6 @@ class UserTokenService
/**
* Generate and store a token for the given user.
*
* @param User $user
*
* @return string
*/
protected function createTokenForUser(User $user): string
{
@@ -102,10 +84,6 @@ class UserTokenService
/**
* Check if the given token exists.
*
* @param string $token
*
* @return bool
*/
protected function tokenExists(string $token): bool
{
@@ -115,12 +93,8 @@ class UserTokenService
/**
* Get a token entry for the given token.
*
* @param string $token
*
* @return object|null
*/
protected function getEntryByToken(string $token)
protected function getEntryByToken(string $token): ?stdClass
{
return DB::table($this->tokenTable)
->where('token', '=', $token)
@@ -129,10 +103,6 @@ class UserTokenService
/**
* Check if the given token entry has expired.
*
* @param stdClass $tokenEntry
*
* @return bool
*/
protected function entryExpired(stdClass $tokenEntry): bool
{

View File

@@ -5,7 +5,6 @@ namespace BookStack\Auth\Permissions;
use BookStack\Auth\Role;
use BookStack\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\MorphTo;
/**
* @property int $id
@@ -23,14 +22,14 @@ class EntityPermission extends Model
protected $fillable = ['role_id', 'view', 'create', 'update', 'delete'];
public $timestamps = false;
/**
* Get this restriction's attached entity.
*/
public function restrictable(): MorphTo
{
return $this->morphTo('restrictable');
}
protected $hidden = ['entity_id', 'entity_type', 'id'];
protected $casts = [
'view' => 'boolean',
'create' => 'boolean',
'read' => 'boolean',
'update' => 'boolean',
'delete' => 'boolean',
];
/**
* Get the role assigned to this entity permission.

View File

@@ -32,6 +32,7 @@ return [
'encryption' => env('MAIL_ENCRYPTION', 'tls'),
'username' => env('MAIL_USERNAME'),
'password' => env('MAIL_PASSWORD'),
'verify_peer' => env('MAIL_VERIFY_SSL', true),
'timeout' => null,
'local_domain' => env('MAIL_EHLO_DOMAIN'),
],

View File

@@ -18,30 +18,11 @@ use BookStack\Entities\Models\PageRevision;
*/
class EntityProvider
{
/**
* @var Bookshelf
*/
public $bookshelf;
/**
* @var Book
*/
public $book;
/**
* @var Chapter
*/
public $chapter;
/**
* @var Page
*/
public $page;
/**
* @var PageRevision
*/
public $pageRevision;
public Bookshelf $bookshelf;
public Book $book;
public Chapter $chapter;
public Page $page;
public PageRevision $pageRevision;
public function __construct()
{
@@ -69,13 +50,18 @@ class EntityProvider
}
/**
* Get an entity instance by it's basic name.
* Get an entity instance by its basic name.
*/
public function get(string $type): Entity
{
$type = strtolower($type);
$instance = $this->all()[$type] ?? null;
return $this->all()[$type];
if (is_null($instance)) {
throw new \InvalidArgumentException("Provided type \"{$type}\" is not a valid entity type");
}
return $instance;
}
/**

View File

@@ -304,7 +304,9 @@ class PageContent
if ($blankIncludes) {
$content = $this->blankPageIncludes($content);
} else {
$content = $this->parsePageIncludes($content);
for ($includeDepth = 0; $includeDepth < 3; $includeDepth++) {
$content = $this->parsePageIncludes($content);
}
}
return $content;

View File

@@ -4,20 +4,20 @@ namespace BookStack\Entities\Tools;
use BookStack\Actions\ActivityType;
use BookStack\Auth\Permissions\EntityPermission;
use BookStack\Auth\Role;
use BookStack\Auth\User;
use BookStack\Entities\Models\Book;
use BookStack\Entities\Models\Bookshelf;
use BookStack\Entities\Models\Entity;
use BookStack\Facades\Activity;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
class PermissionsUpdater
{
/**
* Update an entities permissions from a permission form submit request.
*/
public function updateFromPermissionsForm(Entity $entity, Request $request)
public function updateFromPermissionsForm(Entity $entity, Request $request): void
{
$permissions = $request->get('permissions', null);
$ownerId = $request->get('owned_by', null);
@@ -39,12 +39,44 @@ class PermissionsUpdater
Activity::add(ActivityType::PERMISSIONS_UPDATE, $entity);
}
/**
* Update permissions from API request data.
*/
public function updateFromApiRequestData(Entity $entity, array $data): void
{
if (isset($data['role_permissions'])) {
$entity->permissions()->where('role_id', '!=', 0)->delete();
$rolePermissionData = $this->formatPermissionsFromApiRequestToEntityPermissions($data['role_permissions'] ?? [], false);
$entity->permissions()->createMany($rolePermissionData);
}
if (array_key_exists('fallback_permissions', $data)) {
$entity->permissions()->where('role_id', '=', 0)->delete();
}
if (isset($data['fallback_permissions']['inheriting']) && $data['fallback_permissions']['inheriting'] !== true) {
$data = $data['fallback_permissions'];
$data['role_id'] = 0;
$rolePermissionData = $this->formatPermissionsFromApiRequestToEntityPermissions([$data], true);
$entity->permissions()->createMany($rolePermissionData);
}
if (isset($data['owner_id'])) {
$this->updateOwnerFromId($entity, intval($data['owner_id']));
}
$entity->save();
$entity->rebuildPermissions();
Activity::add(ActivityType::PERMISSIONS_UPDATE, $entity);
}
/**
* Update the owner of the given entity.
* Checks the user exists in the system first.
* Does not save the model, just updates it.
*/
protected function updateOwnerFromId(Entity $entity, int $newOwnerId)
protected function updateOwnerFromId(Entity $entity, int $newOwnerId): void
{
$newOwner = User::query()->find($newOwnerId);
if (!is_null($newOwner)) {
@@ -67,7 +99,41 @@ class PermissionsUpdater
$formatted[] = $entityPermissionData;
}
return $formatted;
return $this->filterEntityPermissionDataUponRole($formatted, true);
}
protected function formatPermissionsFromApiRequestToEntityPermissions(array $permissions, bool $allowFallback): array
{
$formatted = [];
foreach ($permissions as $requestPermissionData) {
$entityPermissionData = ['role_id' => $requestPermissionData['role_id']];
foreach (EntityPermission::PERMISSIONS as $permission) {
$entityPermissionData[$permission] = boolval($requestPermissionData[$permission] ?? false);
}
$formatted[] = $entityPermissionData;
}
return $this->filterEntityPermissionDataUponRole($formatted, $allowFallback);
}
protected function filterEntityPermissionDataUponRole(array $entityPermissionData, bool $allowFallback): array
{
$roleIds = [];
foreach ($entityPermissionData as $permissionEntry) {
$roleIds[] = intval($permissionEntry['role_id']);
}
$actualRoleIds = array_unique(array_values(array_filter($roleIds)));
$rolesById = Role::query()->whereIn('id', $actualRoleIds)->get('id')->keyBy('id');
return array_values(array_filter($entityPermissionData, function ($data) use ($rolesById, $allowFallback) {
if (intval($data['role_id']) === 0) {
return $allowFallback;
}
return $rolesById->has($data['role_id']);
}));
}
/**

View File

@@ -0,0 +1,100 @@
<?php
namespace BookStack\Http\Controllers\Api;
use BookStack\Entities\EntityProvider;
use BookStack\Entities\Models\Entity;
use BookStack\Entities\Tools\PermissionsUpdater;
use Illuminate\Http\Request;
class ContentPermissionApiController extends ApiController
{
public function __construct(
protected PermissionsUpdater $permissionsUpdater,
protected EntityProvider $entities
) {
}
protected $rules = [
'update' => [
'owner_id' => ['int'],
'role_permissions' => ['array'],
'role_permissions.*.role_id' => ['required', 'int', 'exists:roles,id'],
'role_permissions.*.view' => ['required', 'boolean'],
'role_permissions.*.create' => ['required', 'boolean'],
'role_permissions.*.update' => ['required', 'boolean'],
'role_permissions.*.delete' => ['required', 'boolean'],
'fallback_permissions' => ['nullable'],
'fallback_permissions.inheriting' => ['required_with:fallback_permissions', 'boolean'],
'fallback_permissions.view' => ['required_if:fallback_permissions.inheriting,false', 'boolean'],
'fallback_permissions.create' => ['required_if:fallback_permissions.inheriting,false', 'boolean'],
'fallback_permissions.update' => ['required_if:fallback_permissions.inheriting,false', 'boolean'],
'fallback_permissions.delete' => ['required_if:fallback_permissions.inheriting,false', 'boolean'],
]
];
/**
* Read the configured content-level permissions for the item of the given type and ID.
* 'contentType' should be one of: page, book, chapter, bookshelf.
* 'contentId' should be the relevant ID of that item type you'd like to handle permissions for.
* The permissions shown are those that override the default for just the specified item, they do not show the
* full evaluated permission for a role, nor do they reflect permissions inherited from other items in the hierarchy.
* Fallback permission values may be `null` when inheriting is active.
*/
public function read(string $contentType, string $contentId)
{
$entity = $this->entities->get($contentType)
->newQuery()->scopes(['visible'])->findOrFail($contentId);
$this->checkOwnablePermission('restrictions-manage', $entity);
return response()->json($this->formattedPermissionDataForEntity($entity));
}
/**
* Update the configured content-level permission overrides for the item of the given type and ID.
* 'contentType' should be one of: page, book, chapter, bookshelf.
* 'contentId' should be the relevant ID of that item type you'd like to handle permissions for.
* Providing an empty `role_permissions` array will remove any existing configured role permissions,
* so you may want to fetch existing permissions beforehand if just adding/removing a single item.
* You should completely omit the `owner_id`, `role_permissions` and/or the `fallback_permissions` properties
* from your request data if you don't wish to update details within those categories.
*/
public function update(Request $request, string $contentType, string $contentId)
{
$entity = $this->entities->get($contentType)
->newQuery()->scopes(['visible'])->findOrFail($contentId);
$this->checkOwnablePermission('restrictions-manage', $entity);
$data = $this->validate($request, $this->rules()['update']);
$this->permissionsUpdater->updateFromApiRequestData($entity, $data);
return response()->json($this->formattedPermissionDataForEntity($entity));
}
protected function formattedPermissionDataForEntity(Entity $entity): array
{
$rolePermissions = $entity->permissions()
->where('role_id', '!=', 0)
->with(['role:id,display_name'])
->get();
$fallback = $entity->permissions()->where('role_id', '=', 0)->first();
$fallbackData = [
'inheriting' => is_null($fallback),
'view' => $fallback->view ?? null,
'create' => $fallback->create ?? null,
'update' => $fallback->update ?? null,
'delete' => $fallback->delete ?? null,
];
return [
'owner' => $entity->ownedBy()->first(),
'role_permissions' => $rolePermissions,
'fallback_permissions' => $fallbackData,
];
}
}

View File

@@ -0,0 +1,146 @@
<?php
namespace BookStack\Http\Controllers\Api;
use BookStack\Entities\Models\Page;
use BookStack\Uploads\Image;
use BookStack\Uploads\ImageRepo;
use Illuminate\Http\Request;
class ImageGalleryApiController extends ApiController
{
protected array $fieldsToExpose = [
'id', 'name', 'url', 'path', 'type', 'uploaded_to', 'created_by', 'updated_by', 'created_at', 'updated_at',
];
public function __construct(
protected ImageRepo $imageRepo
) {
}
protected function rules(): array
{
return [
'create' => [
'type' => ['required', 'string', 'in:gallery,drawio'],
'uploaded_to' => ['required', 'integer'],
'image' => ['required', 'file', ...$this->getImageValidationRules()],
'name' => ['string', 'max:180'],
],
'update' => [
'name' => ['string', 'max:180'],
]
];
}
/**
* Get a listing of images in the system. Includes gallery (page content) images and drawings.
* Requires visibility of the page they're originally uploaded to.
*/
public function list()
{
$images = Image::query()->scopes(['visible'])
->select($this->fieldsToExpose)
->whereIn('type', ['gallery', 'drawio']);
return $this->apiListingResponse($images, [
...$this->fieldsToExpose
]);
}
/**
* Create a new image in the system.
* Since "image" is expected to be a file, this needs to be a 'multipart/form-data' type request.
* The provided "uploaded_to" should be an existing page ID in the system.
* If the "name" parameter is omitted, the filename of the provided image file will be used instead.
* The "type" parameter should be 'gallery' for page content images, and 'drawio' should only be used
* when the file is a PNG file with diagrams.net image data embedded within.
*/
public function create(Request $request)
{
$this->checkPermission('image-create-all');
$data = $this->validate($request, $this->rules()['create']);
Page::visible()->findOrFail($data['uploaded_to']);
$image = $this->imageRepo->saveNew($data['image'], $data['type'], $data['uploaded_to']);
if (isset($data['name'])) {
$image->refresh();
$image->update(['name' => $data['name']]);
}
return response()->json($this->formatForSingleResponse($image));
}
/**
* View the details of a single image.
* The "thumbs" response property contains links to scaled variants that BookStack may use in its UI.
* The "content" response property provides HTML and Markdown content, in the format that BookStack
* would typically use by default to add the image in page content, as a convenience.
* Actual image file data is not provided but can be fetched via the "url" response property.
*/
public function read(string $id)
{
$image = Image::query()->scopes(['visible'])->findOrFail($id);
return response()->json($this->formatForSingleResponse($image));
}
/**
* Update the details of an existing image in the system.
* Only allows updating of the image name at this time.
*/
public function update(Request $request, string $id)
{
$data = $this->validate($request, $this->rules()['update']);
$image = $this->imageRepo->getById($id);
$this->checkOwnablePermission('page-view', $image->getPage());
$this->checkOwnablePermission('image-update', $image);
$this->imageRepo->updateImageDetails($image, $data);
return response()->json($this->formatForSingleResponse($image));
}
/**
* Delete an image from the system.
* Will also delete thumbnails for the image.
* Does not check or handle image usage so this could leave pages with broken image references.
*/
public function delete(string $id)
{
$image = $this->imageRepo->getById($id);
$this->checkOwnablePermission('page-view', $image->getPage());
$this->checkOwnablePermission('image-delete', $image);
$this->imageRepo->destroyImage($image);
return response('', 204);
}
/**
* Format the given image model for single-result display.
*/
protected function formatForSingleResponse(Image $image): array
{
$this->imageRepo->loadThumbs($image);
$data = $image->getAttributes();
$data['created_by'] = $image->createdBy;
$data['updated_by'] = $image->updatedBy;
$data['content'] = [];
$escapedUrl = htmlentities($image->url);
$escapedName = htmlentities($image->name);
if ($image->type === 'drawio') {
$data['content']['html'] = "<div drawio-diagram=\"{$image->id}\"><img src=\"{$escapedUrl}\"></div>";
$data['content']['markdown'] = $data['content']['html'];
} else {
$escapedDisplayThumb = htmlentities($image->thumbs['display']);
$data['content']['html'] = "<a href=\"{$escapedUrl}\" target=\"_blank\"><img src=\"{$escapedDisplayThumb}\" alt=\"{$escapedName}\"></a>";
$mdEscapedName = str_replace(']', '', str_replace('[', '', $image->name));
$mdEscapedThumb = str_replace(']', '', str_replace('[', '', $image->thumbs['display']));
$data['content']['markdown'] = "![{$mdEscapedName}]({$mdEscapedThumb})";
}
return $data;
}
}

View File

@@ -88,10 +88,10 @@ class RoleApiController extends ApiController
*/
public function read(string $id)
{
$user = $this->permissionsRepo->getRoleById($id);
$this->singleFormatter($user);
$role = $this->permissionsRepo->getRoleById($id);
$this->singleFormatter($role);
return response()->json($user);
return response()->json($role);
}
/**

View File

@@ -14,21 +14,11 @@ use Illuminate\Http\Request;
class ConfirmEmailController extends Controller
{
protected EmailConfirmationService $emailConfirmationService;
protected LoginService $loginService;
protected UserRepo $userRepo;
/**
* Create a new controller instance.
*/
public function __construct(
EmailConfirmationService $emailConfirmationService,
LoginService $loginService,
UserRepo $userRepo
protected EmailConfirmationService $emailConfirmationService,
protected LoginService $loginService,
protected UserRepo $userRepo
) {
$this->emailConfirmationService = $emailConfirmationService;
$this->loginService = $loginService;
$this->userRepo = $userRepo;
}
/**

View File

@@ -10,14 +10,9 @@ use Illuminate\Validation\ValidationException;
class GalleryImageController extends Controller
{
protected $imageRepo;
/**
* GalleryImageController constructor.
*/
public function __construct(ImageRepo $imageRepo)
{
$this->imageRepo = $imageRepo;
public function __construct(
protected ImageRepo $imageRepo
) {
}
/**
@@ -47,9 +42,14 @@ class GalleryImageController extends Controller
public function create(Request $request)
{
$this->checkPermission('image-create-all');
$this->validate($request, [
'file' => $this->getImageValidationRules(),
]);
try {
$this->validate($request, [
'file' => $this->getImageValidationRules(),
]);
} catch (ValidationException $exception) {
return $this->jsonError(implode("\n", $exception->errors()['file']));
}
try {
$imageUpload = $request->file('file');

View File

@@ -151,7 +151,8 @@ class RoleController extends Controller
$this->checkPermission('user-roles-manage');
try {
$this->permissionsRepo->deleteRole($id, $request->get('migrate_role_id', 0));
$migrateRoleId = intval($request->get('migrate_role_id') ?: "0");
$this->permissionsRepo->deleteRole($id, $migrateRoleId);
} catch (PermissionsException $e) {
$this->showErrorNotification($e->getMessage());

View File

@@ -8,11 +8,9 @@ use Illuminate\Http\Request;
class TagController extends Controller
{
protected TagRepo $tagRepo;
public function __construct(TagRepo $tagRepo)
{
$this->tagRepo = $tagRepo;
public function __construct(
protected TagRepo $tagRepo
) {
}
/**

View File

@@ -197,7 +197,7 @@ class UserController extends Controller
$this->checkPermissionOrCurrentUser('users-manage', $id);
$user = $this->userRepo->getById($id);
$newOwnerId = $request->get('new_owner_id', null);
$newOwnerId = intval($request->get('new_owner_id')) ?: null;
$this->userRepo->destroy($user, $newOwnerId);

View File

@@ -173,6 +173,7 @@ class SearchRunner
// Handle exact term matching
foreach ($searchOpts->exacts as $inputTerm) {
$entityQuery->where(function (EloquentBuilder $query) use ($inputTerm, $entityModelInstance) {
$inputTerm = str_replace('\\', '\\\\', $inputTerm);
$query->where('name', 'like', '%' . $inputTerm . '%')
->orWhere($entityModelInstance->textField, 'like', '%' . $inputTerm . '%');
});
@@ -218,6 +219,7 @@ class SearchRunner
$subQuery->where('entity_type', '=', $entity->getMorphClass());
$subQuery->where(function (Builder $query) use ($terms) {
foreach ($terms as $inputTerm) {
$inputTerm = str_replace('\\', '\\\\', $inputTerm);
$query->orWhere('term', 'like', $inputTerm . '%');
}
});
@@ -354,6 +356,9 @@ class SearchRunner
$tagValue = (float) trim($connection->getPdo()->quote($tagValue), "'");
$query->whereRaw("value {$tagOperator} {$tagValue}");
} else {
if ($tagOperator === 'like') {
$tagValue = str_replace('\\', '\\\\', $tagValue);
}
$query->where('value', $tagOperator, $tagValue);
}
} else {

View File

@@ -70,6 +70,19 @@ class ThemeEvents
*/
const COMMONMARK_ENVIRONMENT_CONFIGURE = 'commonmark_environment_configure';
/**
* OIDC ID token pre-validate event.
* Runs just before BookStack validates the user ID token data upon login.
* Provides the existing found set of claims for the user as a key-value array,
* along with an array of the proceeding access token data provided by the identity platform.
* If the listener returns a non-null value, that will replace the existing ID token claim data.
*
* @param array $idTokenData
* @param array $accessTokenData
* @returns array|null
*/
const OIDC_ID_TOKEN_PRE_VALIDATE = 'oidc_id_token_pre_validate';
/**
* Page include parse event.
* Runs when a page include tag is being parsed, typically when page content is being processed for viewing.

View File

@@ -3,9 +3,11 @@
namespace BookStack\Uploads;
use BookStack\Auth\Permissions\JointPermission;
use BookStack\Auth\Permissions\PermissionApplicator;
use BookStack\Entities\Models\Page;
use BookStack\Model;
use BookStack\Traits\HasCreatorAndUpdater;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\HasMany;
@@ -33,12 +35,21 @@ class Image extends Model
->where('joint_permissions.entity_type', '=', 'page');
}
/**
* Scope the query to just the images visible to the user based upon the
* user visibility of the uploaded_to page.
*/
public function scopeVisible(Builder $query): Builder
{
return app()->make(PermissionApplicator::class)->restrictPageRelationQuery($query, 'images', 'uploaded_to');
}
/**
* Get a thumbnail for this image.
*
* @throws \Exception
*/
public function getThumb(int $width, int $height, bool $keepRatio = false): string
public function getThumb(?int $width, ?int $height, bool $keepRatio = false): string
{
return app()->make(ImageService::class)->getThumbnail($this, $width, $height, $keepRatio);
}

View File

@@ -24,6 +24,7 @@ class LanguageManager
'bg' => ['iso' => 'bg_BG', 'windows' => 'Bulgarian'],
'bs' => ['iso' => 'bs_BA', 'windows' => 'Bosnian (Latin)'],
'ca' => ['iso' => 'ca', 'windows' => 'Catalan'],
'cs' => ['iso' => 'cs_CZ', 'windows' => 'Czech'],
'da' => ['iso' => 'da_DK', 'windows' => 'Danish'],
'de' => ['iso' => 'de_DE', 'windows' => 'German'],
'de_informal' => ['iso' => 'de_DE', 'windows' => 'German'],
@@ -120,14 +121,14 @@ class LanguageManager
$isoLang = $this->localeMap[$language]['iso'] ?? '';
$isoLangPrefix = explode('_', $isoLang)[0];
$locales = array_filter([
$locales = array_values(array_filter([
$isoLang ? $isoLang . '.utf8' : false,
$isoLang ?: false,
$isoLang ? str_replace('_', '-', $isoLang) : false,
$isoLang ? $isoLangPrefix . '.UTF-8' : false,
$this->localeMap[$language]['windows'] ?? false,
$language,
]);
]));
if (!empty($locales)) {
setlocale(LC_TIME, $locales[0], ...array_slice($locales, 1));

View File

@@ -147,7 +147,7 @@ function icon(string $name, array $attrs = []): string
}
/**
* Generate a url with multiple parameters for sorting purposes.
* Generate a URL with multiple parameters for sorting purposes.
* Works out the logic to set the correct sorting direction
* Discards empty parameters and allows overriding.
*/
@@ -172,7 +172,7 @@ function sortUrl(string $path, array $data, array $overrideData = []): string
}
if (count($queryStringSections) === 0) {
return $path;
return url($path);
}
return url($path . '?' . implode('&', $queryStringSections));

BIN
bookstack-system-cli Executable file

Binary file not shown.

View File

@@ -49,7 +49,7 @@
"nunomaduro/larastan": "^2.4",
"phpunit/phpunit": "^9.5",
"squizlabs/php_codesniffer": "^3.7",
"ssddanbrown/asserthtml": "^1.0"
"ssddanbrown/asserthtml": "^2.0"
},
"autoload": {
"psr-4": {

482
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,26 @@
{
"owner_id": 1,
"role_permissions": [
{
"role_id": 2,
"view": true,
"create": true,
"update": true,
"delete": false
},
{
"role_id": 3,
"view": false,
"create": false,
"update": false,
"delete": false
}
],
"fallback_permissions": {
"inheriting": false,
"view": true,
"create": true,
"update": false,
"delete": false
}
}

View File

@@ -0,0 +1,3 @@
{
"name": "My updated image name"
}

View File

@@ -7,7 +7,7 @@
"slug": "content-creation",
"description": "How to create documentation on whatever subject you need to write about.",
"priority": 3,
"created_at": "2019-05-05:",
"created_at": "2019-05-05T21:49:56.000000Z",
"updated_at": "2019-09-28T11:24:23.000000Z",
"created_by": 1,
"updated_by": 1,

View File

@@ -0,0 +1,38 @@
{
"owner": {
"id": 1,
"name": "Admin",
"slug": "admin"
},
"role_permissions": [
{
"role_id": 2,
"view": true,
"create": false,
"update": true,
"delete": false,
"role": {
"id": 2,
"display_name": "Editor"
}
},
{
"role_id": 10,
"view": true,
"create": true,
"update": false,
"delete": false,
"role": {
"id": 10,
"display_name": "Wizards of the west"
}
}
],
"fallback_permissions": {
"inheriting": false,
"view": true,
"create": false,
"update": false,
"delete": false
}
}

View File

@@ -0,0 +1,38 @@
{
"owner": {
"id": 1,
"name": "Admin",
"slug": "admin"
},
"role_permissions": [
{
"role_id": 2,
"view": true,
"create": true,
"update": true,
"delete": false,
"role": {
"id": 2,
"display_name": "Editor"
}
},
{
"role_id": 3,
"view": false,
"create": false,
"update": false,
"delete": false,
"role": {
"id": 3,
"display_name": "Viewer"
}
}
],
"fallback_permissions": {
"inheriting": false,
"view": true,
"create": true,
"update": false,
"delete": false
}
}

View File

@@ -0,0 +1,28 @@
{
"name": "cute-cat-image.png",
"path": "\/uploads\/images\/gallery\/2023-03\/cute-cat-image.png",
"url": "https:\/\/bookstack.example.com\/uploads\/images\/gallery\/2023-03\/cute-cat-image.png",
"type": "gallery",
"uploaded_to": 1,
"created_by": {
"id": 1,
"name": "Admin",
"slug": "admin"
},
"updated_by": {
"id": 1,
"name": "Admin",
"slug": "admin"
},
"updated_at": "2023-03-15 08:17:37",
"created_at": "2023-03-15 08:17:37",
"id": 618,
"thumbs": {
"gallery": "https:\/\/bookstack.example.com\/uploads\/images\/gallery\/2023-03\/thumbs-150-150\/cute-cat-image.png",
"display": "https:\/\/bookstack.example.com\/uploads\/images\/gallery\/2023-03\/scaled-1680-\/cute-cat-image.png"
},
"content": {
"html": "<a href=\"https:\/\/bookstack.example.com\/uploads\/images\/gallery\/2023-03\/cute-cat-image.png\" target=\"_blank\"><img src=\"https:\/\/bookstack.example.com\/uploads\/images\/gallery\/2023-03\/scaled-1680-\/cute-cat-image.png\" alt=\"cute-cat-image.png\"><\/a>",
"markdown": "![cute-cat-image.png](https:\/\/bookstack.example.com\/uploads\/images\/gallery\/2023-03\/scaled-1680-\/cute-cat-image.png)"
}
}

View File

@@ -0,0 +1,41 @@
{
"data": [
{
"id": 1,
"name": "My cat scribbles",
"url": "https:\/\/bookstack.example.com\/uploads\/images\/gallery\/2023-02\/scribbles.jpg",
"path": "\/uploads\/images\/gallery\/2023-02\/scribbles.jpg",
"type": "gallery",
"uploaded_to": 1,
"created_by": 1,
"updated_by": 1,
"created_at": "2023-02-12T16:34:57.000000Z",
"updated_at": "2023-02-12T16:34:57.000000Z"
},
{
"id": 2,
"name": "Drawing-1.png",
"url": "https:\/\/bookstack.example.com\/uploads\/images\/drawio\/2023-02\/drawing-1.png",
"path": "\/uploads\/images\/drawio\/2023-02\/drawing-1.png",
"type": "drawio",
"uploaded_to": 2,
"created_by": 2,
"updated_by": 2,
"created_at": "2023-02-12T16:39:19.000000Z",
"updated_at": "2023-02-12T16:39:19.000000Z"
},
{
"id": 8,
"name": "beans.jpg",
"url": "https:\/\/bookstack.example.com\/uploads\/images\/gallery\/2023-02\/beans.jpg",
"path": "\/uploads\/images\/gallery\/2023-02\/beans.jpg",
"type": "gallery",
"uploaded_to": 6,
"created_by": 1,
"updated_by": 1,
"created_at": "2023-02-15T19:37:44.000000Z",
"updated_at": "2023-02-15T19:37:44.000000Z"
}
],
"total": 3
}

View File

@@ -0,0 +1,28 @@
{
"id": 618,
"name": "cute-cat-image.png",
"url": "https:\/\/bookstack.example.com\/uploads\/images\/gallery\/2023-03\/cute-cat-image.png",
"created_at": "2023-03-15 08:17:37",
"updated_at": "2023-03-15 08:17:37",
"created_by": {
"id": 1,
"name": "Admin",
"slug": "admin"
},
"updated_by": {
"id": 1,
"name": "Admin",
"slug": "admin"
},
"path": "\/uploads\/images\/gallery\/2023-03\/cute-cat-image.png",
"type": "gallery",
"uploaded_to": 1,
"thumbs": {
"gallery": "https:\/\/bookstack.example.com\/uploads\/images\/gallery\/2023-03\/thumbs-150-150\/cute-cat-image.png",
"display": "https:\/\/bookstack.example.com\/uploads\/images\/gallery\/2023-03\/scaled-1680-\/cute-cat-image.png"
},
"content": {
"html": "<a href=\"https:\/\/bookstack.example.com\/uploads\/images\/gallery\/2023-03\/cute-cat-image.png\" target=\"_blank\"><img src=\"https:\/\/bookstack.example.com\/uploads\/images\/gallery\/2023-03\/scaled-1680-\/cute-cat-image.png\" alt=\"cute-cat-image.png\"><\/a>",
"markdown": "![cute-cat-image.png](https:\/\/bookstack.example.com\/uploads\/images\/gallery\/2023-03\/scaled-1680-\/cute-cat-image.png)"
}
}

View File

@@ -0,0 +1,28 @@
{
"id": 618,
"name": "My updated image name",
"url": "https:\/\/bookstack.example.com\/uploads\/images\/gallery\/2023-03\/cute-cat-image.png",
"created_at": "2023-03-15 08:17:37",
"updated_at": "2023-03-15 08:24:50",
"created_by": {
"id": 1,
"name": "Admin",
"slug": "admin"
},
"updated_by": {
"id": 1,
"name": "Admin",
"slug": "admin"
},
"path": "\/uploads\/images\/gallery\/2023-03\/cute-cat-image.png",
"type": "gallery",
"uploaded_to": 1,
"thumbs": {
"gallery": "https:\/\/bookstack.example.com\/uploads\/images\/gallery\/2023-03\/thumbs-150-150\/cute-cat-image.png",
"display": "https:\/\/bookstack.example.com\/uploads\/images\/gallery\/2023-03\/scaled-1680-\/cute-cat-image.png"
},
"content": {
"html": "<a href=\"https:\/\/bookstack.example.com\/uploads\/images\/gallery\/2023-03\/cute-cat-image.png\" target=\"_blank\"><img src=\"https:\/\/bookstack.example.com\/uploads\/images\/gallery\/2023-03\/scaled-1680-\/cute-cat-image.png\" alt=\"My updated image name\"><\/a>",
"markdown": "![My updated image name](https:\/\/bookstack.example.com\/uploads\/images\/gallery\/2023-03\/scaled-1680-\/cute-cat-image.png)"
}
}

View File

@@ -1,32 +1,35 @@
#!/usr/bin/env node
const esbuild = require('esbuild');
const fs = require('fs');
const path = require('path');
const fs = require('fs');
// Check if we're building for production
// (Set via passing `production` as first argument)
const isProd = process.argv[2] === 'production';
// Gather our input files
const jsInDir = path.join(__dirname, '../../resources/js');
const jsInDirFiles = fs.readdirSync(jsInDir, 'utf8');
const entryFiles = jsInDirFiles
.filter(f => f.endsWith('.js') || f.endsWith('.mjs'))
.map(f => path.join(jsInDir, f));
const entryPoints = {
app: path.join(__dirname, '../../resources/js/app.js'),
code: path.join(__dirname, '../../resources/js/code/index.mjs'),
'legacy-modes': path.join(__dirname, '../../resources/js/code/legacy-modes.mjs'),
};
// Locate our output directory
const outDir = path.join(__dirname, '../../public/dist');
const outdir = path.join(__dirname, '../../public/dist');
// Build via esbuild
esbuild.build({
bundle: true,
entryPoints: entryFiles,
outdir: outDir,
metafile: true,
entryPoints,
outdir,
sourcemap: true,
target: 'es2020',
mainFields: ['module', 'main'],
format: 'esm',
minify: isProd,
logLevel: "info",
}).then(result => {
fs.writeFileSync('esbuild-meta.json', JSON.stringify(result.metafile));
}).catch(() => process.exit(1));

View File

@@ -33,6 +33,10 @@ If the codebase needs to be tested with deprecations, this can be done via uncom
## Code Standards
We use tools to manage code standards and formatting within the project. If submitting a PR, formatting as per our project standards would help for clarity but don't worry too much about using/understanding these tools as we can always address issues at a later stage when they're picked up by our automated tools.
### PHP
PHP code standards are managed by [using PHP_CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer).
Static analysis is in place using [PHPStan](https://phpstan.org/) & [Larastan](https://github.com/nunomaduro/larastan).
The below commands can be used to utilise these tools:
@@ -51,7 +55,19 @@ composer format
composer check-static
```
If submitting a PR, formatting as per our project standards would help for clarity but don't worry too much about using/understanding these tools as we can always address issues at a later stage when they're picked up by our automated tools.
### JavaScript
JavaScript code standards use managed using [ESLint](https://eslint.org/).
The ESLint rule configuration is managed within the `package.json` file.
The below commands can be used to lint and format:
```bash
# Run code linting using ESLint
npm run lint
# Fix code where possible using ESLint
npm run fix
```
## Development using Docker

View File

@@ -115,6 +115,7 @@ There are various global helper libraries in BookStack which can be accessed via
```js
// HTTP service
// Relative URLs will be resolved against the instance BASE_URL
window.$http.get(url, params);
window.$http.post(url, data);
window.$http.put(url, data);
@@ -153,4 +154,10 @@ window.$components.get(name);
// Get the first active component of the given name that's been
// created on the given element.
window.$components.firstOnElement(element, name);
```
```
## Public Events
There are a range of available events that are emitted as part of a public & supported API for accessing or extending JavaScript libraries & components used in the system.
Details on these events can be found in the [JavaScript Public Events file](javascript-public-events.md).

View File

@@ -0,0 +1,255 @@
# JavaScript Public Events
There are a range of available events emitted as part of a public & [supported](#support) API for accessing or extending JavaScript libraries and components used in the system.
These are emitted via standard DOM events so can be consumed using standard DOM APIs like so:
```javascript
window.addEventListener('event-name', event => {
const eventData = event.detail;
});
```
Such events are typically emitted from a DOM element relevant to event, which then bubbles up.
For most use-cases you can probably just listen on the `window` as shown above.
## Support
This event system, and the events emitted, are considered semi-supported.
Breaking changes of the event API, event names, or event properties, are possible but will be documented in update notes.
The detail provided within the events, and the libraries made accessible, are not considered supported nor stable, and changes to these won't be clearly documented changelogs.
## Event Naming Scheme
Events are typically named in the following format:
```text
<context>::<action/lifecycle>
# Examples:
editor-tinymce::setup
library-cm6::configure-theme
```
If the event is generic in use but specific to a library, the `<context>` will start with `library-` followed by the library name. Otherwise `<context>` may reflect the UI context/component.
The `<action/lifecycle>` reflects the lifecycle stage of the context, or a specific action to perform if the event is specific to a certain use-case.
## Event Listing
### `editor-markdown-cm6::pre-init`
This event is called before the markdown input editor CodeMirror instance is created or loaded.
#### Event Data
- `editorViewConfig` - An [EditorViewConfig](https://codemirror.net/docs/ref/#view.EditorViewConfig) object that will eventially be passed when creating the CodeMirror EditorView instance.
##### Example
```javascript
// Always load the editor with specific pre-defined content if empty
window.addEventListener('editor-markdown-cm6::pre-init', event => {
const config = event.detail.editorViewConfig;
config.doc = config.doc || "Start this page with a nice story";
});
```
### `editor-markdown::setup`
This event is called when the markdown editor loads, post configuration but before the editor is ready to use.
#### Event Data
- `markdownIt` - A references to the [MarkdownIt](https://markdown-it.github.io/markdown-it/#MarkdownIt) instance used to render markdown to HTML (Just for the preview).
- `displayEl` - The IFrame Element that wraps the HTML preview display.
- `cmEditorView` - The CodeMirror [EditorView](https://codemirror.net/docs/ref/#view.EditorView) instance used for the markdown input editor.
##### Example
```javascript
// Set all text in the display to be red by default.
window.addEventListener('editor-markdown::setup', event => {
const display = event.detail.displayEl;
display.contentDocument.body.style.color = 'red';
});
```
### `editor-drawio::configure`
This event is called as the embedded diagrams.net drawing editor loads, to allow configuration of the diagrams.net interface.
See [this diagrams.net page](https://www.diagrams.net/doc/faq/configure-diagram-editor) for details on the available options for the configure event.
If using a custom diagrams.net instance, via the `DRAWIO` option, you will need to ensure your DRAWIO option URL has the `configure=1` query parameter.
#### Event Data
- `config` - The configuration object that will be passed to diagrams.net.
- This will likely be empty by default, but modify this object in-place as needed with your desired options.
##### Example
```javascript
// Set only the "general" and "android" libraries to show by default
window.addEventListener('editor-drawio::configure', event => {
const config = event.detail.config;
config.enabledLibraries = ["general", "android"];
});
```
### `editor-tinymce::pre-init`
This event is called before the TinyMCE editor, used as the BookStack WYSIWYG page editor, is initialised.
#### Event Data
- `config` - Object containing the configuration that's going to be passed to [tinymce.init](https://www.tiny.cloud/docs/api/tinymce/root_tinymce/#init).
##### Example
```javascript
// Removed "bold" from the editor toolbar
window.addEventListener('editor-tinymce::pre-init', event => {
const tinyConfig = event.detail.config;
tinyConfig.toolbar = tinyConfig.toolbar.replace('bold ', '');
});
```
### `editor-tinymce::setup`
This event is called during the `setup` lifecycle stage of the TinyMCE editor used as the BookStack WYSIWYG editor. This is after configuration, but before the editor is fully loaded and ready to use.
##### Event Data
- `editor` - The [tinymce.Editor](https://www.tiny.cloud/docs/api/tinymce/tinymce.editor/) instance used for the WYSIWYG editor.
##### Example
```javascript
// Replaces the editor content with redacted message 3 seconds after load.
window.addEventListener('editor-tinymce::setup', event => {
const editor = event.detail.editor;
setTimeout(() => {
editor.setContent('REDACTED!');
}, 3000);
});
```
### `library-cm6::configure-theme`
This event is called whenever a CodeMirror instance is loaded, as a method to configure the theme used by CodeMirror. This applies to all CodeMirror instances including in-page code blocks, editors using in BookStack settings, and the Page markdown editor.
#### Event Data
- `darkModeActive` - A boolean to indicate if the current view/page is being loaded with dark mode active.
- `registerViewTheme(builder)` - A method that can be called to register a new view (CodeMirror UI) theme.
- `builder` - A function that will return an object that will be passed into the CodeMirror [EditorView.theme()](https://codemirror.net/docs/ref/#view.EditorView^theme) function as a StyleSpec.
- `registerHighlightStyle(builder)` - A method that can be called to register a new HighlightStyle (code highlighting) theme.
- `builder` - A function, that receives a reference to [Tag.tags](https://lezer.codemirror.net/docs/ref/#highlight.tags) and returns an array of [TagStyle](https://codemirror.net/docs/ref/#language.TagStyle) objects.
##### Example
The below shows registering a custom "Solarized dark" editor and syntax theme:
<details>
<summary>Show Example</summary>
```javascript
// Theme data taken from:
// https://github.com/craftzdog/cm6-themes/blob/main/packages/solarized-dark/src/index.ts
// (MIT License) - Copyright (C) 2022 by Takuya Matsuyama and others
const base00 = '#002b36',
base01 = '#073642',
base02 = '#586e75',
base03 = '#657b83',
base04 = '#839496',
base05 = '#93a1a1',
base06 = '#eee8d5',
base07 = '#fdf6e3',
base_red = '#dc322f',
base_orange = '#cb4b16',
base_yellow = '#b58900',
base_green = '#859900',
base_cyan = '#2aa198',
base_blue = '#268bd2',
base_violet = '#6c71c4',
base_magenta = '#d33682'
const invalid = '#d30102',
stone = base04,
darkBackground = '#00252f',
highlightBackground = '#173541',
background = base00,
tooltipBackground = base01,
selection = '#173541',
cursor = base04
function viewThemeBuilder() {
return {
'&':{color:base05,backgroundColor:background},
'.cm-content':{caretColor:cursor},
'.cm-cursor, .cm-dropCursor':{borderLeftColor:cursor},
'&.cm-focused .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection':{backgroundColor:selection},
'.cm-panels':{backgroundColor:darkBackground,color:base03},
'.cm-panels.cm-panels-top':{borderBottom:'2px solid black'},
'.cm-panels.cm-panels-bottom':{borderTop:'2px solid black'},
'.cm-searchMatch':{backgroundColor:'#72a1ff59',outline:'1px solid #457dff'},
'.cm-searchMatch.cm-searchMatch-selected':{backgroundColor:'#6199ff2f'},
'.cm-activeLine':{backgroundColor:highlightBackground},
'.cm-selectionMatch':{backgroundColor:'#aafe661a'},
'&.cm-focused .cm-matchingBracket, &.cm-focused .cm-nonmatchingBracket':{outline:`1px solid ${base06}`},
'.cm-gutters':{backgroundColor:darkBackground,color:stone,border:'none'},
'.cm-activeLineGutter':{backgroundColor:highlightBackground},
'.cm-foldPlaceholder':{backgroundColor:'transparent',border:'none',color:'#ddd'},
'.cm-tooltip':{border:'none',backgroundColor:tooltipBackground},
'.cm-tooltip .cm-tooltip-arrow:before':{borderTopColor:'transparent',borderBottomColor:'transparent'},
'.cm-tooltip .cm-tooltip-arrow:after':{borderTopColor:tooltipBackground,borderBottomColor:tooltipBackground},
'.cm-tooltip-autocomplete':{
'& > ul > li[aria-selected]':{backgroundColor:highlightBackground,color:base03}
}
};
}
function highlightStyleBuilder(t) {
return [{tag:t.keyword,color:base_green},
{tag:[t.name,t.deleted,t.character,t.propertyName,t.macroName],color:base_cyan},
{tag:[t.variableName],color:base05},
{tag:[t.function(t.variableName)],color:base_blue},
{tag:[t.labelName],color:base_magenta},
{tag:[t.color,t.constant(t.name),t.standard(t.name)],color:base_yellow},
{tag:[t.definition(t.name),t.separator],color:base_cyan},
{tag:[t.brace],color:base_magenta},
{tag:[t.annotation],color:invalid},
{tag:[t.number,t.changed,t.annotation,t.modifier,t.self,t.namespace],color:base_magenta},
{tag:[t.typeName,t.className],color:base_orange},
{tag:[t.operator,t.operatorKeyword],color:base_violet},
{tag:[t.tagName],color:base_blue},
{tag:[t.squareBracket],color:base_red},
{tag:[t.angleBracket],color:base02},
{tag:[t.attributeName],color:base05},
{tag:[t.regexp],color:invalid},
{tag:[t.quote],color:base_green},
{tag:[t.string],color:base_yellow},
{tag:t.link,color:base_cyan,textDecoration:'underline',textUnderlinePosition:'under'},
{tag:[t.url,t.escape,t.special(t.string)],color:base_yellow},
{tag:[t.meta],color:base_red},
{tag:[t.comment],color:base02,fontStyle:'italic'},
{tag:t.strong,fontWeight:'bold',color:base06},
{tag:t.emphasis,fontStyle:'italic',color:base_green},
{tag:t.strikethrough,textDecoration:'line-through'},
{tag:t.heading,fontWeight:'bold',color:base_yellow},
{tag:t.heading1,fontWeight:'bold',color:base07},
{tag:[t.heading2,t.heading3,t.heading4],fontWeight:'bold',color:base06},
{tag:[t.heading5,t.heading6],color:base06},
{tag:[t.atom,t.bool,t.special(t.variableName)],color:base_magenta},
{tag:[t.processingInstruction,t.inserted,t.contentSeparator],color:base_red},
{tag:[t.contentSeparator],color:base_yellow},
{tag:t.invalid,color:base02,borderBottom:`1px dotted ${base_red}`}];
}
window.addEventListener('library-cm6::configure-theme', event => {
const detail = event.detail;
detail.registerViewTheme(viewThemeBuilder);
detail.registerHighlightStyle(highlightStyleBuilder);
});
```
</details>

View File

@@ -6,6 +6,9 @@ return [
// Image Manager
'image_select' => 'تحديد صورة',
'image_upload' => 'Upload Image',
'image_intro' => 'Here you can select and manage images that have been previously uploaded to the system.',
'image_intro_upload' => 'Upload a new image by dragging an image file into this window, or by using the "Upload Image" button above.',
'image_all' => 'الكل',
'image_all_title' => 'عرض جميع الصور',
'image_book_title' => 'عرض الصور المرفوعة لهذا الكتاب',
@@ -18,12 +21,12 @@ return [
'image_delete_confirm_text' => 'هل أنت متأكد من أنك تريد حذف هذه الصورة؟',
'image_select_image' => 'تحديد الصورة',
'image_dropzone' => 'قم بإسقاط الصورة أو اضغط هنا للرفع',
'image_dropzone_drop' => 'Drop images here to upload',
'images_deleted' => 'تم حذف الصور',
'image_preview' => 'معاينة الصور',
'image_upload_success' => 'تم رفع الصورة بنجاح',
'image_update_success' => 'تم تحديث تفاصيل الصورة بنجاح',
'image_delete_success' => 'تم حذف الصورة بنجاح',
'image_upload_remove' => 'إزالة',
// Code Editor
'code_editor' => 'تعديل الشفرة',

View File

@@ -311,12 +311,12 @@ return [
'attachments' => 'المرفقات',
'attachments_explain' => 'ارفع بعض الملفات أو أرفق بعض الروابط لعرضها بصفحتك. ستكون الملفات والروابط معروضة في الشريط الجانبي للصفحة.',
'attachments_explain_instant_save' => 'سيتم حفظ التغييرات هنا آنيا.',
'attachments_items' => 'العناصر المرفقة',
'attachments_upload' => 'رفع ملف',
'attachments_link' => 'إرفاق رابط',
'attachments_upload_drop' => 'Alternatively you can drag and drop a file here to upload it as an attachment.',
'attachments_set_link' => 'تحديد الرابط',
'attachments_delete' => 'هل أنت متأكد من أنك تريد حذف هذا المرفق؟',
'attachments_dropzone' => 'أسقط الملفات أو اضغط هنا لإرفاق ملف',
'attachments_dropzone' => 'Drop files here to upload',
'attachments_no_files' => 'لم تُرفع أي ملفات',
'attachments_explain_link' => 'بالإمكان إرفاق رابط في حال عدم تفضيل رفع ملف. قد يكون الرابط لصفحة أخرى أو لملف في أحد خدمات التخزين السحابي.',
'attachments_link_name' => 'اسم الرابط',

View File

@@ -45,7 +45,6 @@ return [
'cannot_create_thumbs' => 'لا يمكن للخادم إنشاء صور مصغرة. الرجاء التأكد من تثبيت إضافة GD PHP.',
'server_upload_limit' => 'الخادم لا يسمح برفع ملفات بهذا الحجم. الرجاء محاولة الرفع بحجم أصغر.',
'uploaded' => 'الخادم لا يسمح برفع ملفات بهذا الحجم. الرجاء محاولة الرفع بحجم أصغر.',
'file_upload_timeout' => 'انتهت عملية تحميل الملف.',
// Drawing & Images
'image_upload_error' => 'حدث خطأ خلال رفع الصورة',
@@ -54,6 +53,7 @@ return [
// Attachments
'attachment_not_found' => 'لم يتم العثور على المرفق',
'attachment_upload_error' => 'An error occurred uploading the attachment file',
// Pages
'page_draft_autosave_fail' => 'فشل حفظ المسودة. الرجاء التأكد من وجود اتصال بالإنترنت قبل حفظ الصفحة',

View File

@@ -50,8 +50,8 @@ return [
// Color settings
'color_scheme' => 'Application Color Scheme',
'color_scheme_desc' => 'Set the colors to use in the BookStack interface. Colors can be configured separately for dark and light modes to best fit the theme and ensure legibility.',
'ui_colors_desc' => 'Set the primary color and default link color for BookStack. The primary color is mainly used for the header banner, buttons and interface decorations. The default link color is used for text-based links and actions, both within written content and in the Bookstack interface.',
'color_scheme_desc' => 'Set the colors to use in the application user interface. Colors can be configured separately for dark and light modes to best fit the theme and ensure legibility.',
'ui_colors_desc' => 'Set the application primary color and default link color. The primary color is mainly used for the header banner, buttons and interface decorations. The default link color is used for text-based links and actions, both within written content and in the application interface.',
'app_color' => 'Primary Color',
'link_color' => 'Default Link Color',
'content_colors_desc' => 'Set colors for all elements in the page organisation hierarchy. Choosing colors with a similar brightness to the default colors is recommended for readability.',

View File

@@ -17,18 +17,18 @@ return [
'page_move' => 'преместена страница',
// Chapters
'chapter_create' => 'създадена страница',
'chapter_create_notification' => 'Главата е добавена успешно',
'chapter_create' => 'създадена глава',
'chapter_create_notification' => 'Успешно създадена глава',
'chapter_update' => 'обновена глава',
'chapter_update_notification' => 'Главата е обновена успешно',
'chapter_update_notification' => 'Успешно обновена глава',
'chapter_delete' => 'изтрита глава',
'chapter_delete_notification' => 'Главата е изтрита успешно',
'chapter_delete_notification' => 'Успешно изтрита глава',
'chapter_move' => 'преместена глава',
// Books
'book_create' => 'създадена книга',
'book_create_notification' => 'Книгата е създадена успешно',
'book_create_from_chapter' => 'converted chapter to book',
'book_create_from_chapter' => 'превърната глава в книга',
'book_create_from_chapter_notification' => 'Chapter successfully converted to a book',
'book_update' => 'обновена книга',
'book_update_notification' => 'Книгата е обновена успешно',
@@ -68,9 +68,9 @@ return [
'user_delete_notification' => 'Потребителят е премахнат успешно',
// Roles
'role_create_notification' => 'Role successfully created',
'role_update_notification' => 'Role successfully updated',
'role_delete_notification' => 'Role successfully deleted',
'role_create_notification' => 'Успешна създадена роля',
'role_update_notification' => 'Успешно обновена роля',
'role_delete_notification' => 'Успешно изтрита роля',
// Other
'commented_on' => 'коментирано на',

View File

@@ -25,23 +25,23 @@ return [
'forgot_password' => 'Забравена парола?',
'remember_me' => 'Запомни ме',
'ldap_email_hint' => 'Моля въведете емейл, който да използвате за дадения профил.',
'create_account' => 'Създай Акаунт',
'create_account' => 'Създаване на акаунт',
'already_have_account' => 'Вече имате профил?',
'dont_have_account' => 'Нямате акаунт?',
'dont_have_account' => 'Нямате ли акаунт?',
'social_login' => 'Влизане по друг начин',
'social_registration' => 'Регистрация по друг начин',
'social_registration_text' => 'Регистрация и вписване чрез друга услуга.',
'social_registration_text' => 'Регистриране и влизане посредством друга услуга.',
'register_thanks' => 'Благодарим Ви за регистрацията!',
'register_thanks' => 'Благодарности за регистрирането!',
'register_confirm' => 'Моля, провери своя имейл адрес и натисни бутона за потвърждение, за да достъпиш :appName.',
'registrations_disabled' => 'Регистрациите към момента са забранени',
'registration_email_domain_invalid' => 'Този емейл домейн към момента няма достъп до приложението',
'register_success' => 'Благодарим Ви за регистрацията! В момента сте регистриран и сте вписани в приложението.',
// Login auto-initiation
'auto_init_starting' => 'Attempting Login',
'auto_init_starting_desc' => 'We\'re contacting your authentication system to start the login process. If there\'s no progress after 5 seconds you can try clicking the link below.',
'auto_init_start_link' => 'Proceed with authentication',
'auto_init_starting' => 'Опит за вход в системата',
'auto_init_starting_desc' => 'Свързахме системата ви за удостоверяване към началото на процеса при влизане. Ако няма напредък след 5 секунди, то може да опитате да щракнете върху долната връзка.',
'auto_init_start_link' => 'Продължаване с удостоверяването',
// Password Reset
'reset_password' => 'Нулиране на паролата',
@@ -56,13 +56,13 @@ return [
// Email Confirmation
'email_confirm_subject' => 'Потвърди емейла си за :appName',
'email_confirm_greeting' => 'Благодарим Ви, че се присъединихте към :appName!',
'email_confirm_text' => 'Моля, потвърдете вашия имейл адрес, като следвате връзката по-долу:',
'email_confirm_text' => 'Потвърдете адреса на имейла си, щраквайки върху връзката по-долу:',
'email_confirm_action' => 'Потвърдете имейл',
'email_confirm_send_error' => 'Нужно ви е потвърждение чрез емейл, но системата не успя да го изпрати. Моля свържете се с администратора, за да проверите дали вашият емейл адрес е конфигуриран правилно.',
'email_confirm_success' => 'Имейлът ти е потвърден! Вече би трябвало да можеш да се впишеш с този имейл адрес.',
'email_confirm_resent' => 'Беше изпратен имейл с потвърждение, Моля, проверете кутията си.',
'email_confirm_thanks' => 'Thanks for confirming!',
'email_confirm_thanks_desc' => 'Please wait a moment while your confirmation is handled. If you are not redirected after 3 seconds press the "Continue" link below to proceed.',
'email_confirm_resent' => 'Е-писмо за потвърждение е изпратено пак, проверете кутията си.',
'email_confirm_thanks' => 'Благодарности за потвърждаването!',
'email_confirm_thanks_desc' => 'Почакайте малко, обработвайки потвърждението ви. Ако не сте пренасочени след 3 секунди, то натиснете долу връзката "Продължаване", за да продължите.',
'email_not_confirmed' => 'Имейл адресът не е потвърден',
'email_not_confirmed_text' => 'Вашият емейл адрес все още не е потвърден.',
@@ -74,9 +74,9 @@ return [
'user_invite_email_subject' => 'Вие бяхте поканен да се присъедините към :appName!',
'user_invite_email_greeting' => 'Беше създаден акаунт за Вас във :appName.',
'user_invite_email_text' => 'Натисните бутона по-долу за да определите парола и да получите достъп:',
'user_invite_email_action' => 'Парола на акаунта',
'user_invite_email_action' => 'Задаване на парола на акаунта',
'user_invite_page_welcome' => 'Добре дошли в :appName!',
'user_invite_page_text' => 'За да финализирате вашият акаунт и да получите достъп трябва да определите парола, която да бъде използвана за следващия влизания в :appName.',
'user_invite_page_text' => 'За да довършвам окончателно акаунта ви и да получите достъп трябва да зададете парола, която ще се използва за влизане в :appName при бъдещи посещения.',
'user_invite_page_confirm_button' => 'Потвърди паролата',
'user_invite_success_login' => 'Паролата е настроена, вече можеш да се впишеш с новата парола, за да достъпиш :appName!',

View File

@@ -6,11 +6,11 @@ return [
// Buttons
'cancel' => 'Отказ',
'confirm' => 'Потвърди',
'confirm' => 'Потвърждаване',
'back' => 'Назад',
'save' => 'Запази',
'continue' => 'Продължи',
'select' => 'Избери',
'save' => 'Запис',
'continue' => 'Продължаване',
'select' => 'Изберете',
'toggle_all' => 'Избери всички',
'more' => 'Повече',
@@ -18,38 +18,38 @@ return [
'name' => 'Име',
'description' => 'Описание',
'role' => 'Роля',
'cover_image' => 'Основно изображение',
'cover_image_description' => 'Картината трябва да е приблизително 440х250 пиксела.',
'cover_image' => 'Образ на корицата',
'cover_image_description' => 'Образът трябва да е горе-долу 440х250 пиксела.',
// Actions
'actions' => 'Действия',
'view' => 'Преглед',
'view_all' => 'Преглед на всички',
'new' => 'New',
'create' => 'Създай',
'new' => 'Ново',
'create' => 'Създаване',
'update' => 'Обновяване',
'edit' => 'Редактиране',
'sort' => 'Сортиране',
'move' => 'Преместване',
'copy' => 'Копирай',
'reply' => 'Отговори',
'delete' => 'Изтрий',
'delete_confirm' => 'Потвърдете изтриването',
'search' => 'Търси',
'search_clear' => 'Изчисти търсенето',
'reset' => 'Нулирай',
'copy' => 'Копиране',
'reply' => 'Отговор',
'delete' => 'Изтриване',
'delete_confirm' => 'Потвърждаване на изтриването',
'search' => 'Търсене',
'search_clear' => 'Изчистване на търсенето',
'reset' => 'Нулиране',
'remove' => 'Премахване',
'add' => 'Добави',
'configure' => 'Конфигурирай',
'fullscreen' => 'Пълен екран',
'favourite' => 'Добави в любими',
'unfavourite' => 'Премахни от любими',
'next' => 'Следващ',
'add' => 'Добавяне',
'configure' => 'Конфигуриране',
'fullscreen' => 'Цял екран',
'favourite' => 'Любимо',
'unfavourite' => 'Не е любимо',
'next' => 'Напред',
'previous' => 'Предишен',
'filter_active' => 'Активен филтър:',
'filter_clear' => 'Изчисти филтъра',
'download' => 'Download',
'open_in_tab' => 'Open in Tab',
'filter_clear' => 'Изчистване на филтрите',
'download' => 'Изтегляне',
'open_in_tab' => 'Отваряне в раздел',
// Sort Options
'sort_options' => 'Опции за сортиране',
@@ -74,27 +74,27 @@ return [
'list_view' => 'Изглед списък',
'default' => 'Основен',
'breadcrumb' => 'Трасиране',
'status' => 'Статус',
'status' => 'Състояние',
'status_active' => 'Активен',
'status_inactive' => 'Неактивен',
'never' => 'Никога',
'none' => 'Няма',
'none' => 'Нищо',
// Header
'homepage' => 'Homepage',
'homepage' => 'Начална страница',
'header_menu_expand' => 'Разшири заглавното меню',
'profile_menu' => 'Профил меню',
'view_profile' => 'Разглеждане на профил',
'profile_menu' => 'Меню на профила',
'view_profile' => 'Преглед на профила',
'edit_profile' => 'Редактиране на профила',
'dark_mode' => 'Тъмен режим',
'light_mode' => 'Светъл режим',
'global_search' => 'Global Search',
'global_search' => 'Глобално търсене',
// Layout tabs
'tab_info' => 'Информация',
'tab_info_label' => 'Таб: Покажи вторична информация',
'tab_info' => 'Инфо.',
'tab_info_label' => 'Раздел: показва вторична информация',
'tab_content' => 'Съдържание',
'tab_content_label' => 'Таб: Покажи първично съдържание',
'tab_content_label' => 'Раздел: Показва първично съдържание',
// Email Content
'email_action_help' => 'Ако имате проблеми с бутона ":actionText" по-горе, копирайте и поставете URL адреса по-долу в уеб браузъра си:',
@@ -102,6 +102,6 @@ return [
// Footer Link Options
// Not directly used but available for convenience to users.
'privacy_policy' => 'Лични данни',
'terms_of_service' => 'Общи условия',
'privacy_policy' => 'Политика за поверителност',
'terms_of_service' => 'Условия на услугата',
];

View File

@@ -6,6 +6,9 @@ return [
// Image Manager
'image_select' => 'Избор на изображение',
'image_upload' => 'Upload Image',
'image_intro' => 'Here you can select and manage images that have been previously uploaded to the system.',
'image_intro_upload' => 'Upload a new image by dragging an image file into this window, or by using the "Upload Image" button above.',
'image_all' => 'Всички',
'image_all_title' => 'Преглед на всички изображения',
'image_book_title' => 'Виж изображенията прикачени към тази книга',
@@ -18,12 +21,12 @@ return [
'image_delete_confirm_text' => 'Сигурни ли сте, че искате да изтриете това изображение?',
'image_select_image' => 'Изберете изображение',
'image_dropzone' => 'Поставете тук изображение или кликнете тук за да качите',
'image_dropzone_drop' => 'Drop images here to upload',
'images_deleted' => 'Изображението е изтрито',
'image_preview' => 'Преглед на изображенията',
'image_upload_success' => 'Изображението бе качено успешно',
'image_update_success' => 'Данните за изобтажението са обновенни успешно',
'image_delete_success' => 'Изображението е успешно изтрито',
'image_upload_remove' => 'Премахване',
// Code Editor
'code_editor' => 'Редактиране на кода',

View File

@@ -9,22 +9,22 @@ return [
// General editor terms
'general' => 'Общи',
'advanced' => 'Разширени',
'none' => 'Няма',
'cancel' => 'Откажи',
'save' => 'Запази',
'close' => 'Затвори',
'undo' => 'Отмени',
'redo' => реправи',
'none' => 'Нищо',
'cancel' => 'Отказ',
'save' => 'Запис',
'close' => 'Затваряне',
'undo' => 'Отмяна',
'redo' => овтаряне',
'left' => 'Вляво',
'center' => 'По средата',
'right' => 'Вдясно',
'top' => 'Отгоре',
'middle' => 'Среда',
'bottom' => 'Отдолу',
'width' => 'Широчина',
'width' => 'Ширина',
'height' => 'Височина',
'More' => 'Още',
'select' => 'Select...',
'select' => 'Изберете...',
// Toolbar
'formats' => 'Формати',
@@ -50,9 +50,9 @@ return [
'custom_color' => 'Цвят по избор',
'remove_color' => 'Премахване на цвят',
'background_color' => 'Фонов цвят',
'align_left' => риравни вляво',
'align_center' => риравни в центъра',
'align_right' => риравни вдясно',
'align_left' => одравняване отляво',
'align_center' => одравняване в средата',
'align_right' => одравняване отдясно',
'align_justify' => 'Justify',
'list_bullet' => 'Списък',
'list_numbered' => 'Номериран списък',
@@ -60,38 +60,38 @@ return [
'indent_increase' => 'Увеличаване на отстъпа',
'indent_decrease' => 'Намаляване на отстъпа',
'table' => 'Таблица',
'insert_image' => 'Вмъкни изображение',
'insert_image_title' => 'Вмъкни/редактирай изображение',
'insert_link' => 'Вмъкни/редактирай връзка',
'insert_image' => 'Вмъкване на образ',
'insert_image_title' => 'Вмъкване/редактиране на образ',
'insert_link' => 'Вмъкване/редактиране на връзка',
'insert_link_title' => 'Вмъкни/редактирай връзка',
'insert_horizontal_line' => 'Вмъкни хоризонтална линия',
'insert_code_block' => 'Въведи код',
'insert_horizontal_line' => 'Вмъкване на хоризонтална линия',
'insert_code_block' => 'Вмъкване на блок код',
'edit_code_block' => 'Edit code block',
'insert_drawing' => 'Вмъкни/редактирай рисунка',
'insert_drawing' => 'Вмъкване/редактиране на рисунка',
'drawing_manager' => 'Управление на рисунките',
'insert_media' => 'Вмъкни/редактирай мултимедия',
'insert_media_title' => 'Вмъкни/редактирай мултимедия',
'clear_formatting' => 'Изчисти форматирането',
'insert_media' => 'Вмъкване/редактиране на мултимедията',
'insert_media_title' => 'Вмъкване/редактиране на мултимедията',
'clear_formatting' => 'Изчистване на форматирането',
'source_code' => 'Изходен код',
'source_code_title' => 'Изходен код',
'fullscreen' => 'Цял екран',
'image_options' => 'Настройки на изображението',
'image_options' => 'Възможности на образа',
// Tables
'table_properties' => 'Настройки на таблицата',
'table_properties_title' => 'Настройки на таблицата',
'delete_table' => 'Изтрий таблицата',
'table_properties' => 'Свойства на таблицата',
'table_properties_title' => 'Свойства на таблица',
'delete_table' => 'Изтриване на таблица',
'insert_row_before' => 'Вмъкни реда преди',
'insert_row_after' => 'Вмъкни реда след',
'delete_row' => 'Изтрий реда',
'delete_row' => 'Изтриване на ред',
'insert_column_before' => 'Вмъкни колоната преди',
'insert_column_after' => 'Вмъкни колоната след',
'delete_column' => 'Изтрий колоната',
'table_cell' => 'Клетка',
'table_row' => 'Ред',
'table_column' => 'Колона',
'cell_properties' => 'Настройки на клетката',
'cell_properties_title' => 'Настройки на клетката',
'cell_properties' => 'Свойства на клетката',
'cell_properties_title' => 'Свойства на клетката',
'cell_type' => 'Тип на клетката',
'cell_type_cell' => 'Клетка',
'cell_scope' => 'Scope',
@@ -115,7 +115,7 @@ return [
'row_type_header' => 'Заглавка',
'row_type_body' => 'Тяло',
'row_type_footer' => 'Долна част',
'alignment' => 'Разположение',
'alignment' => 'Подравняване',
'cut_column' => 'Изрежи колоната',
'copy_column' => 'Копирай колоната',
'paste_column_before' => 'Постави колоната преди',
@@ -148,7 +148,7 @@ return [
'open_link_in' => 'Open link in...',
'open_link_current' => 'Текущ прозорец',
'open_link_new' => 'Нов прозорец',
'remove_link' => 'Remove link',
'remove_link' => 'Премахване на връзка',
'insert_collapsible' => 'Вмъкни сгъваем блок',
'collapsible_unwrap' => 'Разгъни',
'edit_label' => 'Редактирай етикета',
@@ -157,10 +157,10 @@ return [
'toggle_label' => 'Превключи надписа',
// About view
'about' => 'About the editor',
'about' => 'За редактора',
'about_title' => 'Относно визуалния редактор',
'editor_license' => 'Лиценз, авторски и сходни права на редактора',
'editor_tiny_license' => 'This editor is built using :tinyLink which is provided under the MIT license.',
'editor_tiny_license' => 'Този редактор е изграден посредством :tinyLink, което е предоставен под лиценз MIT.',
'editor_tiny_license_link' => 'Авторското и сходните му права, както и лицензът на TinyMCE, могат да бъдат намерени тук.',
'save_continue' => 'Запази страницата и продължи',
'callouts_cycle' => '(Продължавай да натискаш, за да превключваш типовете)',
@@ -168,7 +168,7 @@ return [
'shortcuts' => 'Преки пътища',
'shortcut' => 'Пряк път',
'shortcuts_intro' => 'Следните клавишни комбинации са налични за редактора:',
'windows_linux' => '(Windows/Linux)',
'mac' => '(Mac)',
'windows_linux' => '(Уиндоус/Линукс)',
'mac' => '(Мак.)',
'description' => 'Описание',
];

View File

@@ -311,12 +311,12 @@ return [
'attachments' => 'Прикачени файлове',
'attachments_explain' => 'Прикачете файлове или линкове, които да са видими на вашата страница. Същите ще бъдат видими във вашето странично поле.',
'attachments_explain_instant_save' => 'Промените тук се запазват веднага.',
'attachments_items' => 'Прикачен файл',
'attachments_upload' => 'Прикачен файл',
'attachments_link' => 'Прикачване на линк',
'attachments_upload_drop' => 'Alternatively you can drag and drop a file here to upload it as an attachment.',
'attachments_set_link' => 'Поставяне на линк',
'attachments_delete' => 'Сигурни ли сте, че искате да изтриете прикачения файл?',
'attachments_dropzone' => 'Поставете файлове или цъкнете тук за да прикачите файл',
'attachments_dropzone' => 'Drop files here to upload',
'attachments_no_files' => 'Няма прикачени фалове',
'attachments_explain_link' => 'Може да прикачите линк, ако не искате да качвате файл. Този линк може да бъде към друга страница или към файл в облакова пространство.',
'attachments_link_name' => 'Има на линка',

View File

@@ -45,7 +45,6 @@ return [
'cannot_create_thumbs' => 'Сървърът не може да създаде малки изображения. Моля, увери се, че разширението GD PHP е инсталирано.',
'server_upload_limit' => 'Сървърът не позволява качвания с такъв размер. Моля, пробвайте файл с по-малък размер.',
'uploaded' => 'Сървърът не позволява качвания с такъв размер. Моля, пробвайте файл с по-малък размер.',
'file_upload_timeout' => 'Качването на файла изтече.',
// Drawing & Images
'image_upload_error' => 'Възникна грешка при качването на изображението',
@@ -54,6 +53,7 @@ return [
// Attachments
'attachment_not_found' => 'Прикачения файл не е намерен',
'attachment_upload_error' => 'An error occurred uploading the attachment file',
// Pages
'page_draft_autosave_fail' => 'Неуспешно запазване на черновата. Увери се, че имаш свързаност с интернет преди да запазиш страницата',
@@ -61,7 +61,7 @@ return [
// Entities
'entity_not_found' => 'Обектът не е намерен',
'bookshelf_not_found' => 'Shelf not found',
'bookshelf_not_found' => 'Няма намерен рафт',
'book_not_found' => 'Книгата не е намерена',
'page_not_found' => 'Страницата не е намерена',
'chapter_not_found' => 'Главата не е намерена',

View File

@@ -5,14 +5,14 @@
*/
return [
'shortcuts' => 'Shortcuts',
'shortcuts' => 'Преки пътища',
'shortcuts_interface' => 'Interface Keyboard Shortcuts',
'shortcuts_toggle_desc' => 'Here you can enable or disable keyboard system interface shortcuts, used for navigation and actions.',
'shortcuts_customize_desc' => 'You can customize each of the shortcuts below. Just press your desired key combination after selecting the input for a shortcut.',
'shortcuts_toggle_label' => 'Keyboard shortcuts enabled',
'shortcuts_section_navigation' => 'Navigation',
'shortcuts_section_navigation' => 'Навигация',
'shortcuts_section_actions' => 'Common Actions',
'shortcuts_save' => 'Save Shortcuts',
'shortcuts_save' => 'Запазване на преките пътища',
'shortcuts_overlay_desc' => 'Note: When shortcuts are enabled a helper overlay is available via pressing "?" which will highlight the available shortcuts for actions currently visible on the screen.',
'shortcuts_update_success' => 'Shortcut preferences have been updated!',
'shortcuts_update_success' => 'Обновени предпочитания за преки пътища!',
];

View File

@@ -50,8 +50,8 @@ return [
// Color settings
'color_scheme' => 'Application Color Scheme',
'color_scheme_desc' => 'Set the colors to use in the BookStack interface. Colors can be configured separately for dark and light modes to best fit the theme and ensure legibility.',
'ui_colors_desc' => 'Set the primary color and default link color for BookStack. The primary color is mainly used for the header banner, buttons and interface decorations. The default link color is used for text-based links and actions, both within written content and in the Bookstack interface.',
'color_scheme_desc' => 'Set the colors to use in the application user interface. Colors can be configured separately for dark and light modes to best fit the theme and ensure legibility.',
'ui_colors_desc' => 'Set the application primary color and default link color. The primary color is mainly used for the header banner, buttons and interface decorations. The default link color is used for text-based links and actions, both within written content and in the application interface.',
'app_color' => 'Primary Color',
'link_color' => 'Default Link Color',
'content_colors_desc' => 'Set colors for all elements in the page organisation hierarchy. Choosing colors with a similar brightness to the default colors is recommended for readability.',

View File

@@ -6,6 +6,9 @@ return [
// Image Manager
'image_select' => 'Biraj sliku',
'image_upload' => 'Upload Image',
'image_intro' => 'Here you can select and manage images that have been previously uploaded to the system.',
'image_intro_upload' => 'Upload a new image by dragging an image file into this window, or by using the "Upload Image" button above.',
'image_all' => 'Sve',
'image_all_title' => 'Pogledaj sve slike',
'image_book_title' => 'Pogledaj slike prenesene u ovu knjigu',
@@ -18,12 +21,12 @@ return [
'image_delete_confirm_text' => 'Jeste li sigurni da želite obrisati ovu sliku?',
'image_select_image' => 'Odaberi sliku',
'image_dropzone' => 'Ostavi slike ili pritisnite ovdje da ih prenesete',
'image_dropzone_drop' => 'Drop images here to upload',
'images_deleted' => 'Slike su izbrisane',
'image_preview' => 'Pregled Slike',
'image_upload_success' => 'Slika uspješno učitana',
'image_update_success' => 'Detalji slike uspješno ažurirani',
'image_delete_success' => 'Slika uspješno izbrisana',
'image_upload_remove' => 'Ukloni',
// Code Editor
'code_editor' => 'Uredi Kod',

View File

@@ -311,12 +311,12 @@ return [
'attachments' => 'Prilozi',
'attachments_explain' => 'Učitajte fajlove ili priložite poveznice da bi ih prikazali na stranici. Oni su onda vidljivi u navigaciji sa strane.',
'attachments_explain_instant_save' => 'Sve promjene se snimaju odmah.',
'attachments_items' => 'Priložene stavke',
'attachments_upload' => 'Učitaj fajl',
'attachments_link' => 'Zakači link',
'attachments_upload_drop' => 'Alternatively you can drag and drop a file here to upload it as an attachment.',
'attachments_set_link' => 'Postavi link',
'attachments_delete' => 'Jeste li sigurni da želite obrisati ovaj prilog?',
'attachments_dropzone' => 'Spustite fajlove ili pritisnite ovdje da priložite fajl',
'attachments_dropzone' => 'Drop files here to upload',
'attachments_no_files' => 'Niti jedan fajl nije prenesen',
'attachments_explain_link' => 'Možete zakačiti link ako ne želite učitati fajl. To može biti link druge stranice ili link za fajl u oblaku.',
'attachments_link_name' => 'Naziv linka',

View File

@@ -45,7 +45,6 @@ return [
'cannot_create_thumbs' => 'Server ne može kreirati sličice. Provjerite da imate instaliranu GD PHP ekstenziju.',
'server_upload_limit' => 'Server ne dopušta učitavanja ove veličine. Pokušajte sa manjom veličinom fajla.',
'uploaded' => 'Server ne dopušta učitavanja ove veličine. Pokušajte sa manjom veličinom fajla.',
'file_upload_timeout' => 'Vrijeme učitavanja fajla je isteklo.',
// Drawing & Images
'image_upload_error' => 'Desila se greška prilikom učitavanja slike',
@@ -54,6 +53,7 @@ return [
// Attachments
'attachment_not_found' => 'Prilog nije pronađen',
'attachment_upload_error' => 'An error occurred uploading the attachment file',
// Pages
'page_draft_autosave_fail' => 'Snimanje skice nije uspjelo. Provjerite da ste povezani na internet prije snimanja ove stranice',

View File

@@ -50,8 +50,8 @@ return [
// Color settings
'color_scheme' => 'Application Color Scheme',
'color_scheme_desc' => 'Set the colors to use in the BookStack interface. Colors can be configured separately for dark and light modes to best fit the theme and ensure legibility.',
'ui_colors_desc' => 'Set the primary color and default link color for BookStack. The primary color is mainly used for the header banner, buttons and interface decorations. The default link color is used for text-based links and actions, both within written content and in the Bookstack interface.',
'color_scheme_desc' => 'Set the colors to use in the application user interface. Colors can be configured separately for dark and light modes to best fit the theme and ensure legibility.',
'ui_colors_desc' => 'Set the application primary color and default link color. The primary color is mainly used for the header banner, buttons and interface decorations. The default link color is used for text-based links and actions, both within written content and in the application interface.',
'app_color' => 'Primary Color',
'link_color' => 'Default Link Color',
'content_colors_desc' => 'Set colors for all elements in the page organisation hierarchy. Choosing colors with a similar brightness to the default colors is recommended for readability.',

View File

@@ -6,6 +6,9 @@ return [
// Image Manager
'image_select' => 'Selecciona una imatge',
'image_upload' => 'Upload Image',
'image_intro' => 'Here you can select and manage images that have been previously uploaded to the system.',
'image_intro_upload' => 'Upload a new image by dragging an image file into this window, or by using the "Upload Image" button above.',
'image_all' => 'Totes',
'image_all_title' => 'Mostra totes les imatges',
'image_book_title' => 'Mostra les imatges pujades a aquest llibre',
@@ -18,12 +21,12 @@ return [
'image_delete_confirm_text' => 'Segur que voleu suprimir aquesta imatge?',
'image_select_image' => 'Selecciona una imatge',
'image_dropzone' => 'Arrossegueu imatges o feu clic aquí per a pujar-les',
'image_dropzone_drop' => 'Drop images here to upload',
'images_deleted' => 'Imatges suprimides',
'image_preview' => 'Previsualització de la imatge',
'image_upload_success' => 'Imatge pujada correctament',
'image_update_success' => 'Detalls de la imatge actualitzats correctament',
'image_delete_success' => 'Imatge suprimida correctament',
'image_upload_remove' => 'Suprimeix',
// Code Editor
'code_editor' => 'Edita el codi',

View File

@@ -311,12 +311,12 @@ return [
'attachments' => 'Adjuncions',
'attachments_explain' => 'Pugeu fitxers o adjunteu enllaços per a mostrar-los a la pàgina. Són visibles a la barra lateral de la pàgina.',
'attachments_explain_instant_save' => 'Els canvis fets aquí es desen instantàniament.',
'attachments_items' => 'Elements adjunts',
'attachments_upload' => 'Puja un fitxer',
'attachments_link' => 'Adjunta un enllaç',
'attachments_upload_drop' => 'Alternatively you can drag and drop a file here to upload it as an attachment.',
'attachments_set_link' => 'Defineix l\'enllaç',
'attachments_delete' => 'Seguir que voleu suprimir aquesta adjunció?',
'attachments_dropzone' => 'Arrossegueu fitxers o feu clic aquí per a adjuntar un fitxer',
'attachments_dropzone' => 'Drop files here to upload',
'attachments_no_files' => 'No s\'ha pujat cap fitxer',
'attachments_explain_link' => 'Podeu adjuntar un enllaç si preferiu no pujar un fitxer. Pot ser un enllaç a una altra pàgina o un enllaç a un fitxer al núvol.',
'attachments_link_name' => 'Nom de l\'enllaç',

View File

@@ -45,7 +45,6 @@ return [
'cannot_create_thumbs' => 'El servidor no pot crear miniatures. Reviseu que tingueu instal·lada l\'extensió GD del PHP.',
'server_upload_limit' => 'El servidor no permet pujades d\'aquesta mida. Proveu-ho amb una mida de fitxer més petita.',
'uploaded' => 'El servidor no permet pujades d\'aquesta mida. Proveu-ho amb una mida de fitxer més petita.',
'file_upload_timeout' => 'La pujada del fitxer ha superat el temps màxim d\'espera.',
// Drawing & Images
'image_upload_error' => 'S\'ha produït un error en pujar la imatge',
@@ -54,6 +53,7 @@ return [
// Attachments
'attachment_not_found' => 'No s\'ha trobat l\'adjunció',
'attachment_upload_error' => 'An error occurred uploading the attachment file',
// Pages
'page_draft_autosave_fail' => 'No s\'ha pogut desar l\'esborrany. Assegureu-vos que tingueu connexió a Internet abans de desar la pàgina',

View File

@@ -50,8 +50,8 @@ return [
// Color settings
'color_scheme' => 'Application Color Scheme',
'color_scheme_desc' => 'Set the colors to use in the BookStack interface. Colors can be configured separately for dark and light modes to best fit the theme and ensure legibility.',
'ui_colors_desc' => 'Set the primary color and default link color for BookStack. The primary color is mainly used for the header banner, buttons and interface decorations. The default link color is used for text-based links and actions, both within written content and in the Bookstack interface.',
'color_scheme_desc' => 'Set the colors to use in the application user interface. Colors can be configured separately for dark and light modes to best fit the theme and ensure legibility.',
'ui_colors_desc' => 'Set the application primary color and default link color. The primary color is mainly used for the header banner, buttons and interface decorations. The default link color is used for text-based links and actions, both within written content and in the application interface.',
'app_color' => 'Primary Color',
'link_color' => 'Default Link Color',
'content_colors_desc' => 'Set colors for all elements in the page organisation hierarchy. Choosing colors with a similar brightness to the default colors is recommended for readability.',

View File

@@ -68,9 +68,9 @@ return [
'user_delete_notification' => 'Uživatel byl úspěšně odstraněn',
// Roles
'role_create_notification' => 'Role successfully created',
'role_update_notification' => 'Role successfully updated',
'role_delete_notification' => 'Role successfully deleted',
'role_create_notification' => 'Role byla úspěšně vytvořena',
'role_update_notification' => 'Role byla úspěšně aktualizována',
'role_delete_notification' => 'Role byla odstraněna',
// Other
'commented_on' => 'okomentoval/a',

View File

@@ -6,6 +6,9 @@ return [
// Image Manager
'image_select' => 'Výběr obrázku',
'image_upload' => 'Upload Image',
'image_intro' => 'Here you can select and manage images that have been previously uploaded to the system.',
'image_intro_upload' => 'Upload a new image by dragging an image file into this window, or by using the "Upload Image" button above.',
'image_all' => 'Vše',
'image_all_title' => 'Zobrazit všechny obrázky',
'image_book_title' => 'Zobrazit obrázky nahrané do této knihy',
@@ -18,12 +21,12 @@ return [
'image_delete_confirm_text' => 'Opravdu chcete odstranit tento obrázek?',
'image_select_image' => 'Zvolte obrázek',
'image_dropzone' => 'Přetáhněte obrázky nebo klikněte sem pro nahrání',
'image_dropzone_drop' => 'Drop images here to upload',
'images_deleted' => 'Obrázky odstraněny',
'image_preview' => 'Náhled obrázku',
'image_upload_success' => 'Obrázek byl nahrán',
'image_update_success' => 'Podrobnosti o obrázku byly aktualizovány',
'image_delete_success' => 'Obrázek byl odstraněn',
'image_upload_remove' => 'Odebrat',
// Code Editor
'code_editor' => 'Upravit kód',

View File

@@ -23,7 +23,7 @@ return [
'meta_updated' => 'Aktualizováno :timeLength',
'meta_updated_name' => 'Aktualizováno :timeLength uživatelem :user',
'meta_owned_name' => 'Vlastník :user',
'meta_reference_page_count' => 'Referenced on :count page|Referenced on :count pages',
'meta_reference_page_count' => 'Odkazováno na 1 stránce|Odkazováno na :count stranách',
'entity_select' => 'Výběr entity',
'entity_select_lack_permission' => 'Nemáte dostatečná oprávnění k výběru této položky',
'images' => 'Obrázky',
@@ -311,12 +311,12 @@ return [
'attachments' => 'Přílohy',
'attachments_explain' => 'Nahrajte soubory nebo připojte odkazy, které se zobrazí na stránce. Budou k nalezení v postranní liště.',
'attachments_explain_instant_save' => 'Změny zde provedené se okamžitě ukládají.',
'attachments_items' => 'Připojené položky',
'attachments_upload' => 'Nahrát soubor',
'attachments_link' => 'Připojit odkaz',
'attachments_upload_drop' => 'Alternatively you can drag and drop a file here to upload it as an attachment.',
'attachments_set_link' => 'Nastavit odkaz',
'attachments_delete' => 'Jste si jisti, že chcete odstranit tuto přílohu?',
'attachments_dropzone' => 'Přetáhněte sem soubory myší nebo sem klikněte pro vybrání souboru',
'attachments_dropzone' => 'Drop files here to upload',
'attachments_no_files' => 'Žádné soubory nebyly nahrány',
'attachments_explain_link' => 'Můžete pouze připojit odkaz pokud nechcete nahrávat soubor přímo. Může to být odkaz na jinou stránku nebo na soubor v cloudu.',
'attachments_link_name' => 'Název odkazu',

View File

@@ -45,7 +45,6 @@ return [
'cannot_create_thumbs' => 'Server nedokáže udělat náhledy. Zkontrolujte, že rozšíření GD pro PHP je nainstalováno.',
'server_upload_limit' => 'Server nepovoluje nahrávat tak veliké soubory. Zkuste prosím menší soubor.',
'uploaded' => 'Server nepovoluje nahrávat tak veliké soubory. Zkuste prosím menší soubor.',
'file_upload_timeout' => 'Nahrávání souboru trvalo příliš dlouho a tak bylo ukončeno.',
// Drawing & Images
'image_upload_error' => 'Nastala chyba během nahrávání souboru',
@@ -54,6 +53,7 @@ return [
// Attachments
'attachment_not_found' => 'Příloha nenalezena',
'attachment_upload_error' => 'An error occurred uploading the attachment file',
// Pages
'page_draft_autosave_fail' => 'Nepovedlo se uložit koncept. Než stránku uložíte, ujistěte se, že jste připojeni k internetu.',

View File

@@ -50,8 +50,8 @@ return [
// Color settings
'color_scheme' => 'Barevné schéma aplikace',
'color_scheme_desc' => 'Nastavte barvy pro použití v rozhraní BookStack. Barvy mohou být nastaveny samostatně pro tmavé a světlé režimy, aby se nejlépe vešly do motivu a zajistila čitelnost.',
'ui_colors_desc' => 'Nastavte primární barvu a výchozí barvu odkazů pro BookStack. Hlavní barva se používá hlavně pro banner hlavičky, tlačítka a dekorace rozhraní. Výchozí barva odkazu se používá pro textové odkazy a akce, a to jak v psaném obsahu, tak v rozhraní Bookstack.',
'color_scheme_desc' => 'Nastavte barvy pro uživatelské rozhraní. Barvy mohou být konfigurovány samostatně pro tmavý a světlý režim, aby co nejlépe odpovídaly tématu a zajistily čitelnost.',
'ui_colors_desc' => 'Nastavte primární barvu aplikace a výchozí barvu odkazu. Primární barva je použitá hlavně na banneru hlavičky, tlačítkách a ozdobách rozhraní. Výchozí barva odkazu se používá pro odkazy a akce napříč psaným textem a rozhraním aplikace.',
'app_color' => 'Hlavní barva',
'link_color' => 'Výchozí barva odkazu',
'content_colors_desc' => 'Nastaví barvy pro všechny prvky v organizační struktuře stránky. Pro lepší čitelnost doporučujeme zvolit barvy s podobným jasem, jakou mají výchozí barvy.',
@@ -138,8 +138,8 @@ return [
'roles' => 'Role',
'role_user_roles' => 'Uživatelské role',
'roles_index_desc' => 'Role se používají ke sdružování uživatelů a k poskytování systémových oprávnění jejich členům. Pokud je uživatel členem více rolí, udělená oprávnění budou uložena a uživatel zdědí všechny schopnosti.',
'roles_x_users_assigned' => ':count user assigned|:count users assigned',
'roles_x_permissions_provided' => ':count permission|:count permissions',
'roles_x_users_assigned' => '1 přiřazený uživatel|:count přiřazených uživatelů',
'roles_x_permissions_provided' => '1 oprávnění|:count oprávnění',
'roles_assigned_users' => 'Přiřazení uživatelé',
'roles_permissions_provided' => 'Poskytnutá oprávnění',
'role_create' => 'Vytvořit novou roli',
@@ -249,7 +249,7 @@ return [
// Webhooks
'webhooks' => 'Webhooky',
'webhooks_index_desc' => 'Webhooks jsou způsob, jak odeslat data na externí URL, pokud se vyskytnou určité akce a události v systému, které umožňují integraci událostí s externími platformami, jako jsou systémy zasílání zpráv nebo oznámení.',
'webhooks_x_trigger_events' => ':count trigger event|:count trigger events',
'webhooks_x_trigger_events' => '1 spouštěcí událost|:count spouštěcích událostí',
'webhooks_create' => 'Vytvořit nový webhook',
'webhooks_none_created' => 'Žádné webhooky nebyly doposud vytvořeny.',
'webhooks_edit' => 'Upravit webhook',

View File

@@ -6,6 +6,9 @@ return [
// Image Manager
'image_select' => 'Image Select',
'image_upload' => 'Upload Image',
'image_intro' => 'Here you can select and manage images that have been previously uploaded to the system.',
'image_intro_upload' => 'Upload a new image by dragging an image file into this window, or by using the "Upload Image" button above.',
'image_all' => 'All',
'image_all_title' => 'View all images',
'image_book_title' => 'View images uploaded to this book',
@@ -18,12 +21,12 @@ return [
'image_delete_confirm_text' => 'Are you sure you want to delete this image?',
'image_select_image' => 'Select Image',
'image_dropzone' => 'Drop images or click here to upload',
'image_dropzone_drop' => 'Drop images here to upload',
'images_deleted' => 'Images Deleted',
'image_preview' => 'Image Preview',
'image_upload_success' => 'Image uploaded successfully',
'image_update_success' => 'Image details successfully updated',
'image_delete_success' => 'Image successfully deleted',
'image_upload_remove' => 'Remove',
// Code Editor
'code_editor' => 'Edit Code',

View File

@@ -311,12 +311,12 @@ return [
'attachments' => 'Attachments',
'attachments_explain' => 'Upload some files or attach some links to display on your page. These are visible in the page sidebar.',
'attachments_explain_instant_save' => 'Changes here are saved instantly.',
'attachments_items' => 'Attached Items',
'attachments_upload' => 'Upload File',
'attachments_link' => 'Attach Link',
'attachments_upload_drop' => 'Alternatively you can drag and drop a file here to upload it as an attachment.',
'attachments_set_link' => 'Set Link',
'attachments_delete' => 'Are you sure you want to delete this attachment?',
'attachments_dropzone' => 'Drop files or click here to attach a file',
'attachments_dropzone' => 'Drop files here to upload',
'attachments_no_files' => 'No files have been uploaded',
'attachments_explain_link' => 'You can attach a link if you\'d prefer not to upload a file. This can be a link to another page or a link to a file in the cloud.',
'attachments_link_name' => 'Link Name',

View File

@@ -45,7 +45,6 @@ return [
'cannot_create_thumbs' => 'Ni all y gweinydd greu mân-luniau. Gwiriwch fod gennych yr estyniad GD PHP wedi\'i osod.',
'server_upload_limit' => 'Nid yw\'r gweinydd yn caniatáu uwchlwythiadau o\'r maint hwn. Rhowch gynnig ar faint ffeil llai.',
'uploaded' => 'Nid yw\'r gweinydd yn caniatáu uwchlwythiadau o\'r maint hwn. Rhowch gynnig ar faint ffeil llai.',
'file_upload_timeout' => 'Mae\'r amser uwchlwytho ffeil wedi dod i ben.',
// Drawing & Images
'image_upload_error' => 'Bu gwall wrth uwchlwytho\'r ddelwedd',
@@ -54,6 +53,7 @@ return [
// Attachments
'attachment_not_found' => 'Ni chanfuwyd yr atodiad',
'attachment_upload_error' => 'An error occurred uploading the attachment file',
// Pages
'page_draft_autosave_fail' => 'Wedi methu cadw\'r drafft. Sicrhewch fod gennych gysylltiad rhyngrwyd cyn cadw\'r dudalen hon',

View File

@@ -50,8 +50,8 @@ return [
// Color settings
'color_scheme' => 'Application Color Scheme',
'color_scheme_desc' => 'Set the colors to use in the BookStack interface. Colors can be configured separately for dark and light modes to best fit the theme and ensure legibility.',
'ui_colors_desc' => 'Set the primary color and default link color for BookStack. The primary color is mainly used for the header banner, buttons and interface decorations. The default link color is used for text-based links and actions, both within written content and in the Bookstack interface.',
'color_scheme_desc' => 'Set the colors to use in the application user interface. Colors can be configured separately for dark and light modes to best fit the theme and ensure legibility.',
'ui_colors_desc' => 'Set the application primary color and default link color. The primary color is mainly used for the header banner, buttons and interface decorations. The default link color is used for text-based links and actions, both within written content and in the application interface.',
'app_color' => 'Primary Color',
'link_color' => 'Default Link Color',
'content_colors_desc' => 'Set colors for all elements in the page organisation hierarchy. Choosing colors with a similar brightness to the default colors is recommended for readability.',

View File

@@ -6,6 +6,9 @@ return [
// Image Manager
'image_select' => 'Billedselektion',
'image_upload' => 'Upload Image',
'image_intro' => 'Here you can select and manage images that have been previously uploaded to the system.',
'image_intro_upload' => 'Upload a new image by dragging an image file into this window, or by using the "Upload Image" button above.',
'image_all' => 'Alt',
'image_all_title' => 'Se alle billeder',
'image_book_title' => 'Vis billeder uploadet til denne bog',
@@ -18,12 +21,12 @@ return [
'image_delete_confirm_text' => 'Er du sikker på at du vil slette dette billede?',
'image_select_image' => 'Vælg billede',
'image_dropzone' => 'Træk-og-slip billede eller klik her for at uploade',
'image_dropzone_drop' => 'Drop images here to upload',
'images_deleted' => 'Billede slettet',
'image_preview' => 'Billedeksempel',
'image_upload_success' => 'Foto uploadet',
'image_update_success' => 'Billeddetaljer succesfuldt opdateret',
'image_delete_success' => 'Billede slettet',
'image_upload_remove' => 'Fjern',
// Code Editor
'code_editor' => 'Rediger kode',

View File

@@ -311,12 +311,12 @@ return [
'attachments' => 'Vedhæftninger',
'attachments_explain' => 'Upload nogle filer, eller vedhæft nogle links, der skal vises på siden. Disse er synlige i sidepanelet.',
'attachments_explain_instant_save' => 'Ændringer her gemmes med det samme.',
'attachments_items' => 'Vedhæftede emner',
'attachments_upload' => 'Upload fil',
'attachments_link' => 'Vedhæft link',
'attachments_upload_drop' => 'Alternatively you can drag and drop a file here to upload it as an attachment.',
'attachments_set_link' => 'Sæt link',
'attachments_delete' => 'Er du sikker på at du vil slette denne vedhæftning?',
'attachments_dropzone' => 'Slip filer eller klik her for at vedhæfte en fil',
'attachments_dropzone' => 'Drop files here to upload',
'attachments_no_files' => 'Ingen filer er blevet overført',
'attachments_explain_link' => 'Du kan vedhæfte et link, hvis du foretrækker ikke at uploade en fil. Dette kan være et link til en anden side eller et link til en fil i skyen.',
'attachments_link_name' => 'Linknavn',

View File

@@ -45,7 +45,6 @@ return [
'cannot_create_thumbs' => 'Serveren kan ikke oprette miniaturer. Kontroller, at GD PHP-udvidelsen er installeret.',
'server_upload_limit' => 'Serveren tillader ikke uploads af denne størrelse. Prøv en mindre filstørrelse.',
'uploaded' => 'Serveren tillader ikke uploads af denne størrelse. Prøv en mindre filstørrelse.',
'file_upload_timeout' => 'Filuploaden udløb.',
// Drawing & Images
'image_upload_error' => 'Der opstod en fejl ved upload af billedet',
@@ -54,6 +53,7 @@ return [
// Attachments
'attachment_not_found' => 'Vedhæftning ikke fundet',
'attachment_upload_error' => 'An error occurred uploading the attachment file',
// Pages
'page_draft_autosave_fail' => 'Kunne ikke gemme kladde. Tjek at du har internetforbindelse før du gemmer siden',

View File

@@ -50,8 +50,8 @@ return [
// Color settings
'color_scheme' => 'Application Color Scheme',
'color_scheme_desc' => 'Set the colors to use in the BookStack interface. Colors can be configured separately for dark and light modes to best fit the theme and ensure legibility.',
'ui_colors_desc' => 'Set the primary color and default link color for BookStack. The primary color is mainly used for the header banner, buttons and interface decorations. The default link color is used for text-based links and actions, both within written content and in the Bookstack interface.',
'color_scheme_desc' => 'Set the colors to use in the application user interface. Colors can be configured separately for dark and light modes to best fit the theme and ensure legibility.',
'ui_colors_desc' => 'Set the application primary color and default link color. The primary color is mainly used for the header banner, buttons and interface decorations. The default link color is used for text-based links and actions, both within written content and in the application interface.',
'app_color' => 'Primary Color',
'link_color' => 'Default Link Color',
'content_colors_desc' => 'Set colors for all elements in the page organisation hierarchy. Choosing colors with a similar brightness to the default colors is recommended for readability.',

View File

@@ -6,6 +6,9 @@ return [
// Image Manager
'image_select' => 'Bild auswählen',
'image_upload' => 'Upload Image',
'image_intro' => 'Here you can select and manage images that have been previously uploaded to the system.',
'image_intro_upload' => 'Upload a new image by dragging an image file into this window, or by using the "Upload Image" button above.',
'image_all' => 'Alle',
'image_all_title' => 'Alle Bilder anzeigen',
'image_book_title' => 'Zeige alle Bilder, die in dieses Buch hochgeladen wurden',
@@ -18,12 +21,12 @@ return [
'image_delete_confirm_text' => 'Möchten Sie dieses Bild wirklich löschen?',
'image_select_image' => 'Bild auswählen',
'image_dropzone' => 'Ziehen Sie Bilder hierher oder klicken Sie hier, um ein Bild auszuwählen',
'image_dropzone_drop' => 'Drop images here to upload',
'images_deleted' => 'Bilder gelöscht',
'image_preview' => 'Bildvorschau',
'image_upload_success' => 'Bild erfolgreich hochgeladen',
'image_update_success' => 'Bilddetails erfolgreich aktualisiert',
'image_delete_success' => 'Bild erfolgreich gelöscht',
'image_upload_remove' => 'Entfernen',
// Code Editor
'code_editor' => 'Code editieren',

View File

@@ -311,12 +311,12 @@ return [
'attachments' => 'Anhänge',
'attachments_explain' => 'Sie können auf Ihrer Seite Dateien hochladen oder Links hinzufügen. Diese werden in der Seitenleiste angezeigt.',
'attachments_explain_instant_save' => 'Änderungen werden direkt gespeichert.',
'attachments_items' => 'Angefügte Elemente',
'attachments_upload' => 'Datei hochladen',
'attachments_link' => 'Link hinzufügen',
'attachments_upload_drop' => 'Alternatively you can drag and drop a file here to upload it as an attachment.',
'attachments_set_link' => 'Link setzen',
'attachments_delete' => 'Sind Sie sicher, dass Sie diesen Anhang löschen möchten?',
'attachments_dropzone' => 'Ziehen Sie Dateien hierher oder klicken Sie, um eine Datei auszuwählen',
'attachments_dropzone' => 'Drop files here to upload',
'attachments_no_files' => 'Es wurden bisher keine Dateien hochgeladen.',
'attachments_explain_link' => 'Wenn Sie keine Datei hochladen möchten, können Sie stattdessen einen Link hinzufügen. Dieser Link kann auf eine andere Seite oder eine Datei im Internet weisen.',
'attachments_link_name' => 'Link-Name',

View File

@@ -45,7 +45,6 @@ return [
'cannot_create_thumbs' => 'Der Server kann keine Vorschau-Bilder erzeugen. Bitte prüfen Sie, ob die GD PHP-Erweiterung installiert ist.',
'server_upload_limit' => 'Der Server verbietet das Hochladen von Dateien mit dieser Dateigröße. Bitte versuchen Sie es mit einer kleineren Datei.',
'uploaded' => 'Der Server verbietet das Hochladen von Dateien mit dieser Dateigröße. Bitte versuchen Sie es mit einer kleineren Datei.',
'file_upload_timeout' => 'Der Datei-Upload hat das Zeitlimit überschritten.',
// Drawing & Images
'image_upload_error' => 'Beim Hochladen des Bildes trat ein Fehler auf.',
@@ -54,6 +53,7 @@ return [
// Attachments
'attachment_not_found' => 'Anhang konnte nicht gefunden werden.',
'attachment_upload_error' => 'An error occurred uploading the attachment file',
// Pages
'page_draft_autosave_fail' => 'Fehler beim Speichern des Entwurfs. Stellen Sie sicher, dass Sie mit dem Internet verbunden sind, bevor Sie den Entwurf dieser Seite speichern.',

View File

@@ -33,9 +33,9 @@ return [
'app_custom_html_desc' => 'Jeder Inhalt, der hier hinzugefügt wird, wird am Ende der <head> Sektion jeder Seite eingefügt. Diese kann praktisch sein, um CSS Styles anzupassen oder Analytics-Code hinzuzufügen.',
'app_custom_html_disabled_notice' => 'Benutzerdefinierte HTML-Kopfzeileninhalte sind auf dieser Einstellungsseite deaktiviert, um sicherzustellen, dass alle Änderungen rückgängig gemacht werden können.',
'app_logo' => 'Anwendungslogo',
'app_logo_desc' => 'This is used in the application header bar, among other areas. This image should be 86px in height. Large images will be scaled down.',
'app_icon' => 'Application Icon',
'app_icon_desc' => 'This icon is used for browser tabs and shortcut icons. This should be a 256px square PNG image.',
'app_logo_desc' => 'Dies wird unter anderem in der Kopfzeile der Anwendung verwendet. Dieses Bild sollte 86px hoch sein. Große Bilder werden herunterskaliert.',
'app_icon' => 'Anwendungssymbol',
'app_icon_desc' => 'Dieses Symbol wird für Browser-Registerkarten und Verknüpfungssymbole verwendet. Dies sollte ein 256px quadratisches PNG-Bild sein.',
'app_homepage' => 'Startseite der Anwendung',
'app_homepage_desc' => 'Wählen Sie eine Seite als Startseite aus, die statt der Standardansicht angezeigt werden soll. Seitenberechtigungen werden für die ausgewählten Seiten ignoriert.',
'app_homepage_select' => 'Wählen Sie eine Seite aus',
@@ -49,12 +49,12 @@ return [
'app_disable_comments_desc' => 'Deaktiviert Kommentare über alle Seiten in der Anwendung. Vorhandene Kommentare werden nicht angezeigt.',
// Color settings
'color_scheme' => 'Application Color Scheme',
'color_scheme_desc' => 'Set the colors to use in the BookStack interface. Colors can be configured separately for dark and light modes to best fit the theme and ensure legibility.',
'ui_colors_desc' => 'Set the primary color and default link color for BookStack. The primary color is mainly used for the header banner, buttons and interface decorations. The default link color is used for text-based links and actions, both within written content and in the Bookstack interface.',
'app_color' => 'Primary Color',
'link_color' => 'Default Link Color',
'content_colors_desc' => 'Set colors for all elements in the page organisation hierarchy. Choosing colors with a similar brightness to the default colors is recommended for readability.',
'color_scheme' => 'Farbschema der Anwendung',
'color_scheme_desc' => 'Lege die Farben, die in der Benutzeroberfläche verwendet werden, fest. Farben können separat für dunkle und helle Modi konfiguriert werden, um am besten zum Farbschema zu passen und die Lesbarkeit zu gewährleisten.',
'ui_colors_desc' => 'Lege die primäre Farbe und die Standard-Linkfarbe der Anwendung fest. Die primäre Farbe wird hauptsächlich für Kopfzeilen, Buttons und Interface-Dekorationen verwendet. Die Standard-Linkfarbe wird für textbasierte Links und Aktionen sowohl innerhalb des geschriebenen Inhalts als auch in der Benutzeroberfläche verwendet.',
'app_color' => 'Primäre Farbe',
'link_color' => 'Standard-Linkfarbe',
'content_colors_desc' => 'Legt Farben für alle Elemente in der Seitenorganisationshierarchie fest. Die Auswahl von Farben mit einer ähnlichen Helligkeit wie die Standardfarben wird zur Lesbarkeit empfohlen.',
'bookshelf_color' => 'Regalfarbe',
'book_color' => 'Buchfarbe',
'chapter_color' => 'Kapitelfarbe',
@@ -139,8 +139,8 @@ Hinweis: Benutzer können ihre E-Mail-Adresse nach erfolgreicher Registrierung
'roles' => 'Rollen',
'role_user_roles' => 'Benutzer-Rollen',
'roles_index_desc' => 'Rollen werden verwendet, um Benutzer zu gruppieren System-Berechtigung für ihre Mitglieder zuzuweisen. Wenn ein Benutzer Mitglied mehrerer Rollen ist, stapeln die gewährten Berechtigungen und der Benutzer wird alle Fähigkeiten erben.',
'roles_x_users_assigned' => ':count user assigned|:count users assigned',
'roles_x_permissions_provided' => ':count permission|:count permissions',
'roles_x_users_assigned' => ':count Benutzer zugewiesen|:count Benutzer zugewiesen',
'roles_x_permissions_provided' => ':count Berechtigung|:count Berechtigungen',
'roles_assigned_users' => 'Zugewiesene Benutzer',
'roles_permissions_provided' => 'Genutzte Berechtigungen',
'role_create' => 'Neue Rolle anlegen',
@@ -250,7 +250,7 @@ Hinweis: Benutzer können ihre E-Mail-Adresse nach erfolgreicher Registrierung
// Webhooks
'webhooks' => 'Webhooks',
'webhooks_index_desc' => 'Webhooks sind eine Möglichkeit, Daten an externe URLs zu senden, wenn bestimmte Aktionen und Ereignisse im System auftreten, was eine ereignisbasierte Integration mit externen Plattformen wie Messaging- oder Benachrichtigungssystemen ermöglicht.',
'webhooks_x_trigger_events' => ':count trigger event|:count trigger events',
'webhooks_x_trigger_events' => ':count Auslöserereignis|:count Auslöserereignisse',
'webhooks_create' => 'Neuen Webhook erstellen',
'webhooks_none_created' => 'Es wurden noch keine Webhooks erstellt.',
'webhooks_edit' => 'Webhook bearbeiten',

View File

@@ -68,7 +68,7 @@ return [
'user_delete_notification' => 'Benutzer erfolgreich entfernt',
// Roles
'role_create_notification' => 'Rolle erfolgreich angelegt',
'role_create_notification' => 'Rolle erfolgreich erstellt',
'role_update_notification' => 'Rolle erfolgreich aktualisiert',
'role_delete_notification' => 'Rolle erfolgreich gelöscht',

View File

@@ -6,6 +6,9 @@ return [
// Image Manager
'image_select' => 'Bild auswählen',
'image_upload' => 'Upload Image',
'image_intro' => 'Here you can select and manage images that have been previously uploaded to the system.',
'image_intro_upload' => 'Upload a new image by dragging an image file into this window, or by using the "Upload Image" button above.',
'image_all' => 'Alle',
'image_all_title' => 'Alle Bilder anzeigen',
'image_book_title' => 'Zeige alle Bilder, die in dieses Buch hochgeladen wurden',
@@ -18,12 +21,12 @@ return [
'image_delete_confirm_text' => 'Bist Du sicher, dass Du diese Seite löschen möchtest?',
'image_select_image' => 'Bild auswählen',
'image_dropzone' => 'Ziehe Bilder hierher oder klicke hier, um ein Bild auszuwählen',
'image_dropzone_drop' => 'Drop images here to upload',
'images_deleted' => 'Bilder gelöscht',
'image_preview' => 'Bildvorschau',
'image_upload_success' => 'Bild erfolgreich hochgeladen',
'image_update_success' => 'Bilddetails erfolgreich aktualisiert',
'image_delete_success' => 'Bild erfolgreich gelöscht',
'image_upload_remove' => 'Entfernen',
// Code Editor
'code_editor' => 'Code editieren',

View File

@@ -141,7 +141,7 @@ return [
'books_search_this' => 'Dieses Buch durchsuchen',
'books_navigation' => 'Buchnavigation',
'books_sort' => 'Buchinhalte sortieren',
'books_sort_desc' => 'Kapitel und Seiten innerhalb eines Buches verschieben, um dessen Inhalt zu reorganisieren. Andere Bücher können hinzugefügt werden, was das Verschieben von Kapiteln und Seiten zwischen Büchern erleichtert.',
'books_sort_desc' => 'Kapitel und Seiten innerhalb eines Buches verschieben, um dessen Inhalt neu zu ordnen. Andere Bücher können hinzugefügt werden, was das Verschieben von Kapiteln und Seiten zwischen Büchern erleichtert.',
'books_sort_named' => 'Buch ":bookName" sortieren',
'books_sort_name' => 'Sortieren nach Namen',
'books_sort_created' => 'Sortieren nach Erstellungsdatum',
@@ -150,15 +150,15 @@ return [
'books_sort_chapters_last' => 'Kapitel zuletzt',
'books_sort_show_other' => 'Andere Bücher anzeigen',
'books_sort_save' => 'Neue Reihenfolge speichern',
'books_sort_show_other_desc' => 'Füge hier weitere Bücher hinzu, um sie in die Sortierung einzubinden und ermögliche so eine einfache und übergreifende Reorganisation.',
'books_sort_show_other_desc' => 'Füge hier weitere Bücher hinzu, um sie in die Sortierung einzubinden und ermögliche so eine einfache und übergreifende Neuordnung.',
'books_sort_move_up' => 'Nach oben bewegen',
'books_sort_move_down' => 'Nach unten bewegen',
'books_sort_move_prev_book' => 'Zum vorherigen Buch verschieben',
'books_sort_move_next_book' => 'Zum nächsten Buch verschieben',
'books_sort_move_prev_chapter' => 'In das vorherige Kapitel verschieben',
'books_sort_move_next_chapter' => 'In nächstes Kapitel verschieben',
'books_sort_move_prev_chapter' => 'Ins vorherige Kapitel verschieben',
'books_sort_move_next_chapter' => 'Ins nächste Kapitel verschieben',
'books_sort_move_book_start' => 'Zum Buchbeginn verschieben',
'books_sort_move_book_end' => 'Zum Ende des Buches verschieben',
'books_sort_move_book_end' => 'Zum Buchende verschieben',
'books_sort_move_before_chapter' => 'Vor Kapitel verschieben',
'books_sort_move_after_chapter' => 'Nach Kapitel verschieben',
'books_copy' => 'Buch kopieren',
@@ -311,12 +311,12 @@ return [
'attachments' => 'Anhänge',
'attachments_explain' => 'Du kannst auf deiner Seite Dateien hochladen oder Links hinzufügen. Diese werden in der Seitenleiste angezeigt.',
'attachments_explain_instant_save' => 'Änderungen werden direkt gespeichert.',
'attachments_items' => 'Angefügte Elemente',
'attachments_upload' => 'Datei hochladen',
'attachments_link' => 'Link hinzufügen',
'attachments_upload_drop' => 'Alternatively you can drag and drop a file here to upload it as an attachment.',
'attachments_set_link' => 'Link setzen',
'attachments_delete' => 'Bist du sicher, dass du diesen Anhang löschen möchtest?',
'attachments_dropzone' => 'Ziehe Dateien hierher oder klicke hier, um eine Datei auszuwählen',
'attachments_dropzone' => 'Drop files here to upload',
'attachments_no_files' => 'Es wurden bisher keine Dateien hochgeladen.',
'attachments_explain_link' => 'Wenn du keine Datei hochladen möchtest, kannst du stattdessen einen Link hinzufügen. Dieser Link kann auf eine andere Seite oder eine Datei im Internet verweisen.',
'attachments_link_name' => 'Link-Name',

View File

@@ -45,15 +45,15 @@ return [
'cannot_create_thumbs' => 'Der Server kann keine Vorschau-Bilder erzeugen. Bitte prüfe, ob die GD PHP-Erweiterung installiert ist.',
'server_upload_limit' => 'Der Server verbietet das Hochladen von Dateien mit dieser Dateigröße. Bitte versuche es mit einer kleineren Datei.',
'uploaded' => 'Der Server verbietet das Hochladen von Dateien mit dieser Dateigröße. Bitte versuche es mit einer kleineren Datei.',
'file_upload_timeout' => 'Der Upload der Datei ist abgelaufen.',
// Drawing & Images
'image_upload_error' => 'Beim Hochladen des Bildes trat ein Fehler auf.',
'image_upload_type_error' => 'Der Bildtyp der hochgeladenen Datei ist ungültig.',
'drawing_data_not_found' => 'Zeichnungsdaten konnten nicht geladen werden. Die Zeichnungsdatei existiert möglicherweise nicht mehr oder Sie haben nicht die Berechtigung, darauf zuzugreifen.',
'drawing_data_not_found' => 'Zeichnungsdaten konnten nicht geladen werden. Die Zeichnungsdatei existiert möglicherweise nicht mehr oder du hast nicht die Berechtigung, darauf zuzugreifen.',
// Attachments
'attachment_not_found' => 'Anhang konnte nicht gefunden werden.',
'attachment_upload_error' => 'An error occurred uploading the attachment file',
// Pages
'page_draft_autosave_fail' => 'Fehler beim Speichern des Entwurfs. Stelle sicher, dass du mit dem Internet verbunden bist, bevor du den Entwurf dieser Seite speicherst.',

View File

@@ -33,9 +33,9 @@ return [
'app_custom_html_desc' => 'Jeder Inhalt, der hier hinzugefügt wird, wird am Ende der <head> Sektion jeder Seite eingefügt. Diese kann praktisch sein, um CSS Styles anzupassen oder Analytics-Code hinzuzufügen.',
'app_custom_html_disabled_notice' => 'Benutzerdefinierte HTML-Kopfzeileninhalte sind auf dieser Einstellungsseite deaktiviert, um sicherzustellen, dass alle Änderungen rückgängig gemacht werden können.',
'app_logo' => 'Anwendungslogo',
'app_logo_desc' => 'This is used in the application header bar, among other areas. This image should be 86px in height. Large images will be scaled down.',
'app_icon' => 'Application Icon',
'app_icon_desc' => 'This icon is used for browser tabs and shortcut icons. This should be a 256px square PNG image.',
'app_logo_desc' => 'Dies wird unter anderem in der Kopfzeile der Anwendung verwendet. Dieses Bild sollte 86px hoch sein. Große Bilder werden herunterskaliert.',
'app_icon' => 'Anwendungssymbol',
'app_icon_desc' => 'Dieses Symbol wird für Browser-Registerkarten und Verknüpfungssymbole verwendet. Dies sollte ein 256px quadratisches PNG-Bild sein.',
'app_homepage' => 'Startseite der Anwendung',
'app_homepage_desc' => 'Wähle eine Seite als Startseite aus, die statt der Standardansicht angezeigt werden soll. Seitenberechtigungen werden für die ausgewählten Seiten ignoriert.',
'app_homepage_select' => 'Wähle eine Seite aus',
@@ -49,12 +49,12 @@ return [
'app_disable_comments_desc' => 'Deaktiviert Kommentare über alle Seiten in der Anwendung. Vorhandene Kommentare werden nicht angezeigt.',
// Color settings
'color_scheme' => 'Application Color Scheme',
'color_scheme_desc' => 'Set the colors to use in the BookStack interface. Colors can be configured separately for dark and light modes to best fit the theme and ensure legibility.',
'ui_colors_desc' => 'Set the primary color and default link color for BookStack. The primary color is mainly used for the header banner, buttons and interface decorations. The default link color is used for text-based links and actions, both within written content and in the Bookstack interface.',
'app_color' => 'Primary Color',
'link_color' => 'Default Link Color',
'content_colors_desc' => 'Set colors for all elements in the page organisation hierarchy. Choosing colors with a similar brightness to the default colors is recommended for readability.',
'color_scheme' => 'Farbschema der Anwendung',
'color_scheme_desc' => 'Lege die Farben, die in der Benutzeroberfläche verwendet werden, fest. Farben können separat für dunkle und helle Modi konfiguriert werden, um am besten zum Farbschema zu passen und die Lesbarkeit zu gewährleisten.',
'ui_colors_desc' => 'Lege die primäre Farbe und die Standard-Linkfarbe der Anwendung fest. Die primäre Farbe wird hauptsächlich für Kopfzeilen, Buttons und Interface-Dekorationen verwendet. Die Standard-Linkfarbe wird für textbasierte Links und Aktionen sowohl innerhalb des geschriebenen Inhalts als auch in der Benutzeroberfläche verwendet.',
'app_color' => 'Primäre Farbe',
'link_color' => 'Standard-Linkfarbe',
'content_colors_desc' => 'Lege Farben für alle Elemente in der Seitenorganisationshierarchie fest. Die Auswahl von Farben mit einer ähnlichen Helligkeit wie die Standardfarben wird zur Lesbarkeit empfohlen.',
'bookshelf_color' => 'Regalfarbe',
'book_color' => 'Buchfarbe',
'chapter_color' => 'Kapitelfarbe',
@@ -139,8 +139,8 @@ Hinweis: Benutzer können ihre E-Mail Adresse nach erfolgreicher Registrierung
'roles' => 'Rollen',
'role_user_roles' => 'Benutzer-Rollen',
'roles_index_desc' => 'Rollen werden verwendet, um Benutzer zu gruppieren und System-Berechtigungen für ihre Mitglieder zuzuweisen. Wenn ein Benutzer Mitglied mehrerer Rollen ist, stapeln die gewährten Berechtigungen und der Benutzer wird alle Fähigkeiten erben.',
'roles_x_users_assigned' => ':count user assigned|:count users assigned',
'roles_x_permissions_provided' => ':count permission|:count permissions',
'roles_x_users_assigned' => ':count Benutzer zugewiesen|:count Benutzer zugewiesen',
'roles_x_permissions_provided' => ':count Berechtigung|:count Berechtigungen',
'roles_assigned_users' => 'Zugewiesene Benutzer',
'roles_permissions_provided' => 'Genutzte Berechtigungen',
'role_create' => 'Neue Rolle anlegen',
@@ -250,7 +250,7 @@ Hinweis: Benutzer können ihre E-Mail Adresse nach erfolgreicher Registrierung
// Webhooks
'webhooks' => 'Webhooks',
'webhooks_index_desc' => 'Webhooks sind eine Möglichkeit, Daten an externe URLs zu senden, wenn bestimmte Aktionen und Ereignisse im System auftreten, was eine ereignisbasierte Integration mit externen Plattformen wie Messaging- oder Benachrichtigungssystemen ermöglicht.',
'webhooks_x_trigger_events' => ':count trigger event|:count trigger events',
'webhooks_x_trigger_events' => ':count Auslöserereignis|:count Auslöserereignisse',
'webhooks_create' => 'Neuen Webhook erstellen',
'webhooks_none_created' => 'Es wurden noch keine Webhooks erstellt.',
'webhooks_edit' => 'Webhook bearbeiten',

View File

@@ -68,9 +68,9 @@ return [
'user_delete_notification' => 'Ο Χρήστης αφαιρέθηκε επιτυχώς',
// Roles
'role_create_notification' => 'Role successfully created',
'role_update_notification' => 'Role successfully updated',
'role_delete_notification' => 'Role successfully deleted',
'role_create_notification' => 'Ο Ρόλος δημιουργήθηκε με επιτυχία',
'role_update_notification' => 'Ο Ρόλος ενημερώθηκε με επιτυχία',
'role_delete_notification' => 'Ο Ρόλος διαγράφηκε επιτυχώς',
// Other
'commented_on' => 'σχολίασε',

View File

@@ -6,6 +6,9 @@ return [
// Image Manager
'image_select' => 'Επιλογή εικόνας',
'image_upload' => 'Upload Image',
'image_intro' => 'Here you can select and manage images that have been previously uploaded to the system.',
'image_intro_upload' => 'Upload a new image by dragging an image file into this window, or by using the "Upload Image" button above.',
'image_all' => 'Όλες',
'image_all_title' => 'Δείτε όλες τις εικόνες που υπάρχουν στο Server',
'image_book_title' => 'Προβολή εικόνων που έχουν μεταφορτωθεί σε αυτό το βιβλίο',
@@ -18,12 +21,12 @@ return [
'image_delete_confirm_text' => 'Είστε σίγουροι ότι θέλετε να διαγράψετε αυτήν την εικόνα;',
'image_select_image' => 'Επιλέξτε Εικόνα',
'image_dropzone' => 'Σύρτε ή κάντε κλικ εδώ για μεταφόρτωση εικόνων',
'image_dropzone_drop' => 'Drop images here to upload',
'images_deleted' => 'Οι εικόνες διαγράφηκαν',
'image_preview' => 'Προεπισκόπηση εικόνας',
'image_upload_success' => 'Η εικόνα μεταφορτώθηκε με επιτυχία',
'image_update_success' => 'Τα στοιχεία της εικόνας ενημερώθηκαν με επιτυχία',
'image_delete_success' => 'Η εικόνα διαγράφηκε επιτυχώς',
'image_upload_remove' => 'Αφαίρεση',
// Code Editor
'code_editor' => 'Επεξεργασία κώδικα',

View File

@@ -19,11 +19,11 @@ return [
'revisions' => 'Αναθεωρήσεις',
'meta_revision' => 'Αναθεώρηση #:revisionCount',
'meta_created' => 'Δημιουργήθηκε :timeLength',
'meta_created_name' => 'Δημιουργήθηκε :timeLength by :user',
'meta_created_name' => 'Δημιουργήθηκε :timeLength από :user',
'meta_updated' => 'Ενημερώθηκε :timeLength',
'meta_updated_name' => 'Ενημερώθηκε :timeLength by :user',
'meta_updated_name' => 'Ενημερώθηκε :timeLength από :user',
'meta_owned_name' => 'Ανήκει στον :user',
'meta_reference_page_count' => 'Referenced on :count page|Referenced on :count pages',
'meta_reference_page_count' => 'Αναφορά σε :count σελίδας|Αναφορά στο :count σελίδες',
'entity_select' => 'Επιλογή Οντότητας',
'entity_select_lack_permission' => 'Δεν έχετε τα απαιτούμενα δικαιώματα για να επιλέξετε αυτό το στοιχείο',
'images' => 'Εικόνες',
@@ -43,18 +43,18 @@ return [
// Permissions and restrictions
'permissions' => 'Δικαιώματα',
'permissions_desc' => 'Ορίστε εδώ δικαιώματα για να παρακάμψετε τα προκαθορισμένα δικαιώματα που παρέχονται από τους ρόλους των χρηστών.',
'permissions_book_cascade' => 'Permissions set on books will automatically cascade to child chapters and pages, unless they have their own permissions defined.',
'permissions_chapter_cascade' => 'Permissions set on chapters will automatically cascade to child pages, unless they have their own permissions defined.',
'permissions_book_cascade' => 'Τα δικαιώματα που έχουν οριστεί στα Βιβλία θα κλιμακώνονται αυτόματα στα θυγατρικά Κεφάλαια και Σελίδες, εκτός εάν έχουν καθοριστεί διαφορετικά σε αυτά.',
'permissions_chapter_cascade' => 'Τα δικαιώματα που έχουν οριστεί στα Κεφάλαια θα κλιμακώνονται αυτόματα στις θυγατρικές Σελίδες, εκτός εάν έχουν καθοριστεί διαφορετικά σε αυτές.',
'permissions_save' => 'Αποθήκευση Δικαιωμάτων',
'permissions_owner' => 'Ιδιοκτήτης / Κάτοχος',
'permissions_role_everyone_else' => 'Everyone Else',
'permissions_role_everyone_else' => 'Όλοι Οι Άλλοι',
'permissions_role_everyone_else_desc' => 'Ορίστε δικαιώματα για όλους τους ρόλους που δεν παραβλέπονται συγκεκριμένα.',
'permissions_role_override' => 'Παράκαμψη δικαιωμάτων για ρόλο',
'permissions_inherit_defaults' => 'Κληρονόμηση προεπιλογών',
// Search
'search_results' => 'Αποτελέσματα αναζήτησης',
'search_total_results_found' => ':count αποτέλεσμα που βρέθηκε:count συνολικά αποτελέσματα που βρέθηκαν',
'search_total_results_found' => 'Βρέθηκε :count αποτέλεσμα|Βρέθηκαν συνολικά :count αποτελέσματα',
'search_clear' => 'Καθαρισμός αναζήτησης',
'search_no_pages' => 'Καμία σελίδα δεν ταιριάζει με αυτήν την αναζήτηση',
'search_for_term' => 'Αναζήτηση για :term',
@@ -65,7 +65,7 @@ return [
'search_exact_matches' => 'Ακριβείς αντιστοιχίες',
'search_tags' => 'Αναζητήσεις Ετικετών',
'search_options' => 'Επιλογές',
'search_viewed_by_me' => 'Προβλήθηκε από μένα',
'search_viewed_by_me' => 'Προβλήθηκε από εμένα',
'search_not_viewed_by_me' => 'Δεν προβλήθηκε από εμένα',
'search_permissions_set' => 'Τα δικαιώματα ορίστηκαν',
'search_created_by_me' => 'Δημιουργήθηκε από εμένα',
@@ -141,7 +141,7 @@ return [
'books_search_this' => 'Αναζήτηση σε αυτό το βιβλίο',
'books_navigation' => 'Πλοήγηση Βιβλίου',
'books_sort' => 'Ταξινόμηση Περιεχομένων Βιβλίου',
'books_sort_desc' => 'Move chapters and pages within a book to reorganise its contents. Other books can be added which allows easy moving of chapters and pages between books.',
'books_sort_desc' => 'Μετακινήστε κεφάλαια και σελίδες μέσα σε ένα βιβλίο για να αναδιοργανώσετε τα περιεχόμενά του. Μπορούν να προστεθούν και άλλα βιβλία, και επιτρέπουν την εύκολη μετακίνηση κεφαλαίων και σελίδων μεταξύ βιβλίων.',
'books_sort_named' => 'Ταξινόμηση Βιβλίου :bookname',
'books_sort_name' => 'Ταξινόμηση κατά όνομα',
'books_sort_created' => 'Ταξινόμηση κατά ημερομηνία δημιουργίας',
@@ -150,24 +150,24 @@ return [
'books_sort_chapters_last' => 'Τελευταία Κεφάλαια',
'books_sort_show_other' => 'Εμφάνιση Άλλων Βιβλίων',
'books_sort_save' => 'Αποθήκευση Νέας Ταξινόμησης',
'books_sort_show_other_desc' => 'Add other books here to include them in the sort operation, and allow easy cross-book reorganisation.',
'books_sort_move_up' => 'Move Up',
'books_sort_move_down' => 'Move Down',
'books_sort_move_prev_book' => 'Move to Previous Book',
'books_sort_move_next_book' => 'Move to Next Book',
'books_sort_move_prev_chapter' => 'Move Into Previous Chapter',
'books_sort_move_next_chapter' => 'Move Into Next Chapter',
'books_sort_move_book_start' => 'Move to Start of Book',
'books_sort_move_book_end' => 'Move to End of Book',
'books_sort_move_before_chapter' => 'Move to Before Chapter',
'books_sort_move_after_chapter' => 'Move to After Chapter',
'books_sort_show_other_desc' => 'Προσθέστε άλλα βιβλία εδώ για να τα συμπεριλάβετε στην ταξινόμηση και να επιτρέψετε την εύκολη αναδιοργάνωση μεταξύ των βιβλίων.',
'books_sort_move_up' => 'Μετακίνηση προς τα Επάνω',
'books_sort_move_down' => 'Μετακίνηση προς τα Κάτω',
'books_sort_move_prev_book' => 'Μετακίνηση στο προηγούμενο Βιβλίο',
'books_sort_move_next_book' => 'Μετακίνηση στο επόμενο Βιβλίο',
'books_sort_move_prev_chapter' => 'Μετακίνηση στο προηγούμενο Κεφάλαιο',
'books_sort_move_next_chapter' => 'Μετακίνηση στο επόμενο Κεφάλαιο',
'books_sort_move_book_start' => 'Μετακίνηση στην Αρχή του Βιβλίου',
'books_sort_move_book_end' => 'Μετακίνηση στο Τέλος του Βιβλίου',
'books_sort_move_before_chapter' => 'Μετακίνηση στο προηγούμενο Κεφάλαιο',
'books_sort_move_after_chapter' => 'Μετακίνηση στο επόμενο Κεφάλαιο',
'books_copy' => 'Αντιγραφή Βιβλίου',
'books_copy_success' => 'Το βιβλίο αντιγράφηκε επιτυχώς',
// Chapters
'chapter' => 'Κεφάλαιο',
'chapters' => 'Κεφάλαια',
'x_chapters' => ':count Κεφάλαιο:count Κεφάλαια',
'x_chapters' => ':count Κεφάλαιο|:count Κεφάλαια',
'chapters_popular' => 'Δημοφιλή Κεφάλαια',
'chapters_new' => 'Νέο Κεφάλαιο',
'chapters_create' => 'Δημιουργία Νέου Κεφαλαίου',
@@ -193,7 +193,7 @@ return [
// Pages
'page' => 'Σελίδα',
'pages' => 'Σελίδες',
'x_pages' => ':count Σελίδα:count Σελίδες',
'x_pages' => ':count Σελίδα|:count Σελίδες',
'pages_popular' => 'Δημοφιλείς Σελίδες',
'pages_new' => 'Νέα Σελίδα',
'pages_attachments' => 'Συνημμένα',
@@ -248,7 +248,7 @@ return [
'pages_permissions_success' => 'Τα δικαιώματα σελίδας ενημερώθηκαν',
'pages_revision' => 'Αναθεώρηση',
'pages_revisions' => 'Αναθεωρήσεις Σελίδας',
'pages_revisions_desc' => 'Listed below are all the past revisions of this page. You can look back upon, compare, and restore old page versions if permissions allow. The full history of the page may not be fully reflected here since, depending on system configuration, old revisions could be auto-deleted.',
'pages_revisions_desc' => 'Παρακάτω αναφέρονται όλες οι προηγούμενες αναθεωρήσεις αυτής της Σελίδας. Μπορείτε να αναζητήσετε αντίγραφα ασφαλείας, να συγκρίνετε και να επαναφέρετε παλιές εκδόσεις Σελίδας, εάν τα δικαιώματα το επιτρέπουν. Το πλήρες ιστορικό της Σελίδας μπορεί να μην αντανακλάται πλήρως εδώ επειδή, ανάλογα με τη διαμόρφωση του συστήματος, οι παλιές αναθεωρήσεις θα μπορούσαν να διαγραφούν αυτόματα.',
'pages_revisions_named' => 'Αναθεωρήσεις σελίδας για :pageName',
'pages_revision_named' => 'Αναθεώρηση σελίδας για :pageName',
'pages_revision_restored_from' => 'Επαναφορά από #:id; :summary',
@@ -292,7 +292,7 @@ return [
'shelf_tags' => 'Ετικέτες Ραφιών',
'tag' => 'Ετικέτα',
'tags' => 'Ετικέτες',
'tags_index_desc' => 'Tags can be applied to content within the system to apply a flexible form of categorization. Tags can have both a key and value, with the value being optional. Once applied, content can then be queried using the tag name and value.',
'tags_index_desc' => 'Οι Ετικέτες μπορούν να εφαρμοστούν στο περιεχόμενο μέσα στο σύστημα για να εφαρμοστεί μια ευέλικτη μορφή κατηγοριοποίησης. Οι Ετικέτες μπορούν να έχουν τόσο κλειδί όσο και αξία, με την τιμή να είναι προαιρετική. Μόλις εφαρμοστεί, μπορεί να παρθεί περιεχόμενο χρησιμοποιώντας το όνομα της Ετικέτας και την τιμή.',
'tag_name' => 'Όνομα Ετικέτας',
'tag_value' => 'Τιμή Ετικέτας (Προαιρετικό)',
'tags_explain' => "Προσθέστε μερικές ετικέτες για να κατηγοριοποιήσετε καλύτερα το περιεχόμενό σας. \n Μπορείτε να αντιστοιχίσετε μια τιμή σε μια ετικέτα για πιο αναλυτική οργάνωση.",
@@ -311,12 +311,12 @@ return [
'attachments' => 'Συνημμένα',
'attachments_explain' => 'Ανεβάστε μερικά αρχεία ή επισυνάψτε μερικούς συνδέσμους για να εμφανίσετε στη σελίδα σας. Αυτά είναι ορατά στην πλαϊνή μπάρα σελίδας.',
'attachments_explain_instant_save' => 'Οι αλλαγές εδώ αποθηκεύονται αμέσως.',
'attachments_items' => 'Συνημμένα Στοιχεία',
'attachments_upload' => 'Μεταφόρτωση Αρχείου',
'attachments_link' => 'Επισύναψη Δεσμού',
'attachments_upload_drop' => 'Alternatively you can drag and drop a file here to upload it as an attachment.',
'attachments_set_link' => 'Ορισμός Συνδέσμου',
'attachments_delete' => 'Είστε βέβαιοι ότι θέλετε να διαγράψετε αυτό το συνημμένο;',
'attachments_dropzone' => 'Αποθέστε αρχεία ή κάντε κλικ εδώ για να επισυνάψετε ένα αρχείο',
'attachments_dropzone' => 'Drop files here to upload',
'attachments_no_files' => 'Δεν έχουν μεταφορτωθεί αρχεία',
'attachments_explain_link' => 'Μπορείτε να επισυνάψετε έναν σύνδεσμο αν προτιμάτε να μην ανεβάσετε ένα αρχείο. Αυτό μπορεί να είναι ένας σύνδεσμος σε άλλη σελίδα ή ένας σύνδεσμος σε ένα αρχείο στο σύννεφο.',
'attachments_link_name' => 'Όνομα Συνδέσμου',
@@ -354,7 +354,7 @@ return [
'comments' => 'Σχόλια',
'comment_add' => 'Προσθήκη Σχολίου',
'comment_placeholder' => 'Αφήστε ένα σχόλιο εδώ',
'comment_count' => '{0} Κανένα σχόλιο{1} 1 Σχόλιο [2,*] :count Σχόλια',
'comment_count' => '{0} Κανένα Σχόλιο |{1} 1 Σχόλιο |[2,*] :count Σχόλια',
'comment_save' => 'Αποθήκευση Σχολίου',
'comment_saving' => 'Αποθήκευση σχολίου...',
'comment_deleting' => 'Διαγραφή σχολίου...',

View File

@@ -45,15 +45,15 @@ return [
'cannot_create_thumbs' => 'Ο διακομιστής δεν μπορεί να δημιουργήσει μικρογραφίες. Παρακαλώ ελέγξτε ότι έχετε την επέκταση GD PHP εγκατεστημένη.',
'server_upload_limit' => 'Ο διακομιστής δεν επιτρέπει τη μεταφόρτωση αυτού του μεγέθους. Παρακαλώ δοκιμάστε ένα μικρότερο μέγεθος αρχείου.',
'uploaded' => 'Ο διακομιστής δεν επιτρέπει τη μεταφόρτωση αυτού του μεγέθους. Παρακαλώ δοκιμάστε ένα μικρότερο μέγεθος αρχείου.',
'file_upload_timeout' => 'Το χρονικό όριο μεταφόρτωσης αρχείου έληξε.',
// Drawing & Images
'image_upload_error' => 'Παρουσιάστηκε σφάλμα κατά το ανέβασμα της εικόνας.',
'image_upload_type_error' => 'Ο τύπος εικόνας που μεταφορτώθηκε δεν είναι έγκυρος',
'drawing_data_not_found' => 'Drawing data could not be loaded. The drawing file might no longer exist or you may not have permission to access it.',
'drawing_data_not_found' => 'Δεν ήταν δυνατή η φόρτωση δεδομένων σχεδίασης. Το αρχείο σχεδίασης ενδέχεται να μην υπάρχει πλέον ή ενδέχεται να μην έχετε άδεια πρόσβασης σε αυτά.',
// Attachments
'attachment_not_found' => 'Το συνημμένο δεν βρέθηκε',
'attachment_upload_error' => 'An error occurred uploading the attachment file',
// Pages
'page_draft_autosave_fail' => 'Αποτυχία αποθήκευσης προσχέδιου. Βεβαιωθείτε ότι έχετε σύνδεση στο διαδίκτυο πριν την αποθήκευση αυτής της σελίδας',

View File

@@ -33,9 +33,9 @@ return [
'app_custom_html_desc' => 'Οποιοδήποτε περιεχόμενο προστίθεται εδώ θα εισαχθεί στο κάτω μέρος της ενότητας <head> κάθε σελίδας. Αυτό είναι βολικό για την παράκαμψη ή προσθήκη στυλ καθώς και την προσθήκη κώδικα αναλυτικών στοιχείων.',
'app_custom_html_disabled_notice' => 'Το προσαρμοσμένο περιεχόμενο κεφαλίδας HTML είναι απενεργοποιημένο σε αυτήν τη σελίδα ρυθμίσεων, για να διασφαλιστεί ότι τυχόν αλλαγές που θα πραγματοποιηθούν και θα προκαλέσουν δυσλειτουργία στην ιστοσελίδα σας, μπορούν να επαναφερθούν.',
'app_logo' => 'Λογότυπο εφαρμογής',
'app_logo_desc' => 'This is used in the application header bar, among other areas. This image should be 86px in height. Large images will be scaled down.',
'app_icon' => 'Application Icon',
'app_icon_desc' => 'This icon is used for browser tabs and shortcut icons. This should be a 256px square PNG image.',
'app_logo_desc' => 'Αυτό χρησιμοποιείται στη γραμμή κεφαλίδας εφαρμογής, μεταξύ άλλων περιοχών. Αυτή η εικόνα θα πρέπει να είναι 86px σε ύψος. Οι μεγάλες εικόνες θα κλιμακωθούν.',
'app_icon' => 'Εικονίδιο Εφαρμογής',
'app_icon_desc' => 'Αυτό το εικονίδιο χρησιμοποιείται για τις καρτέλες περιηγητή και τα εικονίδια συντομεύσεων. Αυτό πρέπει να είναι μια τετράγωνη εικόνα 256px σε μορφή PNG.',
'app_homepage' => 'Αρχική σελίδα εφαρμογής',
'app_homepage_desc' => 'Επιλέξτε μια προβολή για εμφάνιση στην αρχική σελίδα αντί για την προεπιλεγμένη προβολή. Τα δικαιώματα σελίδων αγνοούνται για επιλεγμένες σελίδες.',
'app_homepage_select' => 'Επιλέξτε μια σελίδα',
@@ -49,12 +49,12 @@ return [
'app_disable_comments_desc' => 'Απενεργοποιεί τα σχόλια σε όλες τις σελίδες της εφαρμογής. <br> Τα υπάρχοντα σχόλια δεν εμφανίζονται.',
// Color settings
'color_scheme' => 'Application Color Scheme',
'color_scheme_desc' => 'Set the colors to use in the BookStack interface. Colors can be configured separately for dark and light modes to best fit the theme and ensure legibility.',
'ui_colors_desc' => 'Set the primary color and default link color for BookStack. The primary color is mainly used for the header banner, buttons and interface decorations. The default link color is used for text-based links and actions, both within written content and in the Bookstack interface.',
'app_color' => 'Primary Color',
'link_color' => 'Default Link Color',
'content_colors_desc' => 'Set colors for all elements in the page organisation hierarchy. Choosing colors with a similar brightness to the default colors is recommended for readability.',
'color_scheme' => 'Θέμα Χρωμάτων Εφαρμογής',
'color_scheme_desc' => 'Ορίστε τα χρώματα που θα χρησιμοποιηθούν στο περιβάλλον χρήστη της εφαρμογής. Τα χρώματα μπορούν να ρυθμιστούν ξεχωριστά για τις λειτουργίες Σκούρο ή Λευκό, για να ταιριάζει καλύτερα στο θέμα και να εξασφαλίσει αναγνωσιμότητα.',
'ui_colors_desc' => 'Ορίστε το πρωτεύον χρώμα της εφαρμογής και το προεπιλεγμένο χρώμα συνδέσμου. Το πρωτεύον χρώμα χρησιμοποιείται κυρίως για την κεφαλίδα, τα κουμπιά και τις διακοσμήσεις διεπαφής. Το προεπιλεγμένο χρώμα συνδέσμου χρησιμοποιείται για συνδέσμους και ενέργειες που βασίζονται στο κείμενο, τόσο μέσα στο γραπτό περιεχόμενο όσο και στη διεπαφή της εφαρμογής.',
'app_color' => 'Κυρίως χρώμα',
'link_color' => 'Κυρίως χρώμα Συνδέσμου',
'content_colors_desc' => 'Ορίζει τα χρώματα για όλα τα στοιχεία στην ιεραρχία οργάνωσης της ιστοσελίδας. Συνιστάται η επιλογή χρωμάτων με παρόμοια φωτεινότητα με τα προεπιλεγμένα, για μέγιστη αναγνωσιμότητα.',
'bookshelf_color' => 'Χρώμα Ραφιού',
'book_color' => 'Χρώμα Βιβλίων',
'chapter_color' => 'Χρώμα Κεφαλαίων Βιβλίων',
@@ -137,9 +137,9 @@ return [
// Role Settings
'roles' => 'Ρόλοι',
'role_user_roles' => 'Ρόλοι Χρηστών',
'roles_index_desc' => 'Roles are used to group users & provide system permission to their members. When a user is a member of multiple roles the privileges granted will stack and the user will inherit all abilities.',
'roles_x_users_assigned' => ':count user assigned|:count users assigned',
'roles_x_permissions_provided' => ':count permission|:count permissions',
'roles_index_desc' => 'Οι Ρόλοι χρησιμοποιούνται για την ομαδοποίηση των χρηστών και παρέχουν δικαιώματα για το σύστημα στα μέλη τους. Όταν ένας χρήστης είναι μέλος πολλαπλών Ρόλων, ο χρήστης θα κληρονομεί όλες τις ιδιότητες από όλους τους Ρόλους που ανήκει.',
'roles_x_users_assigned' => ':count εκχωρημένος χρήστης|:count εκχωρημένοι χρήστες',
'roles_x_permissions_provided' => ':count άδεια|:count άδειες',
'roles_assigned_users' => 'Εκχωρημένοι χρήστες',
'roles_permissions_provided' => 'Παρεχόμενα Δικαιώματα',
'role_create' => 'Δημιουργία νέου ρόλου',
@@ -178,7 +178,7 @@ return [
// Users
'users' => 'Χρήστες',
'users_index_desc' => 'Create & manage individual user accounts within the system. User accounts are used for login and attribution of content & activity. Access permissions are primarily role-based but user content ownership, among other factors, may also affect permissions & access.',
'users_index_desc' => 'Δημιουργία & διαχείριση μεμονωμένων λογαριασμών χρήστη μέσα στο σύστημα. Οι λογαριασμοί χρήστη χρησιμοποιούνται για τη σύνδεση και την απόδοση του περιεχομένου & δραστηριότητα. Τα δικαιώματα πρόσβασης βασίζονται κυρίως σε Ρόλους, αλλά η κυριότητα του περιεχομένου του χρήστη, μεταξύ άλλων παραγόντων, μπορεί επίσης να επηρεάσει τα δικαιώματα & την πρόσβαση.',
'user_profile' => 'Προφίλ Χρήστη',
'users_add_new' => 'Προσθήκη νέου Χρήστη',
'users_search' => 'Αναζήτηση Χρηστών',
@@ -222,7 +222,7 @@ return [
'users_api_tokens_docs' => 'Τεκμηρίωση API',
'users_mfa' => 'Έλεγχος Ταυτοτητας Πολλαπλων Παραγοντων',
'users_mfa_desc' => 'Ρυθμίστε τον έλεγχο ταυτότητας πολλαπλών παραγόντων ως ένα επιπλέον επίπεδο ασφάλειας για τον λογαριασμό χρήστη σας.',
'users_mfa_x_methods' => ':count μέθοδος έχει ρυθμιστεί:count μέθοδοι',
'users_mfa_x_methods' => 'Έχει ρυθμιστεί :count μέθοδος|Έχουν ρυθμιστεί :count μέθοδοι',
'users_mfa_configure' => 'Ρύθμιση Μεθόδων',
// API Tokens
@@ -248,8 +248,8 @@ return [
// Webhooks
'webhooks' => 'Webhooks',
'webhooks_index_desc' => 'Webhooks are a way to send data to external URLs when certain actions and events occur within the system which allows event-based integration with external platforms such as messaging or notification systems.',
'webhooks_x_trigger_events' => ':count trigger event|:count trigger events',
'webhooks_index_desc' => 'Τα Webhooks είναι ένας τρόπος αποστολής δεδομένων σε εξωτερικές διευθύνσεις URL όταν ορισμένες ενέργειες και συμβάντα συμβαίνουν στο σύστημα που επιτρέπει την ενσωμάτωση με εξωτερικές πλατφόρμες όπως συστήματα μηνυμάτων ή ειδοποιήσεων.',
'webhooks_x_trigger_events' => ':count συμβάν ενεργοποίησης|:count συμβάντα ενεργοποίησης',
'webhooks_create' => 'Δημιουργία νέου Webhook',
'webhooks_none_created' => 'Δεν έχουν δημιουργηθεί ακόμη webhook.',
'webhooks_edit' => 'Επεξεργασία Webhook',

View File

@@ -6,6 +6,9 @@ return [
// Image Manager
'image_select' => 'Image Select',
'image_upload' => 'Upload Image',
'image_intro' => 'Here you can select and manage images that have been previously uploaded to the system.',
'image_intro_upload' => 'Upload a new image by dragging an image file into this window, or by using the "Upload Image" button above.',
'image_all' => 'All',
'image_all_title' => 'View all images',
'image_book_title' => 'View images uploaded to this book',
@@ -18,12 +21,12 @@ return [
'image_delete_confirm_text' => 'Are you sure you want to delete this image?',
'image_select_image' => 'Select Image',
'image_dropzone' => 'Drop images or click here to upload',
'image_dropzone_drop' => 'Drop images here to upload',
'images_deleted' => 'Images Deleted',
'image_preview' => 'Image Preview',
'image_upload_success' => 'Image uploaded successfully',
'image_update_success' => 'Image details successfully updated',
'image_delete_success' => 'Image successfully deleted',
'image_upload_remove' => 'Remove',
// Code Editor
'code_editor' => 'Edit Code',

View File

@@ -311,12 +311,12 @@ return [
'attachments' => 'Attachments',
'attachments_explain' => 'Upload some files or attach some links to display on your page. These are visible in the page sidebar.',
'attachments_explain_instant_save' => 'Changes here are saved instantly.',
'attachments_items' => 'Attached Items',
'attachments_upload' => 'Upload File',
'attachments_link' => 'Attach Link',
'attachments_upload_drop' => 'Alternatively you can drag and drop a file here to upload it as an attachment.',
'attachments_set_link' => 'Set Link',
'attachments_delete' => 'Are you sure you want to delete this attachment?',
'attachments_dropzone' => 'Drop files or click here to attach a file',
'attachments_dropzone' => 'Drop files here to upload',
'attachments_no_files' => 'No files have been uploaded',
'attachments_explain_link' => 'You can attach a link if you\'d prefer not to upload a file. This can be a link to another page or a link to a file in the cloud.',
'attachments_link_name' => 'Link Name',

View File

@@ -45,7 +45,6 @@ return [
'cannot_create_thumbs' => 'The server cannot create thumbnails. Please check you have the GD PHP extension installed.',
'server_upload_limit' => 'The server does not allow uploads of this size. Please try a smaller file size.',
'uploaded' => 'The server does not allow uploads of this size. Please try a smaller file size.',
'file_upload_timeout' => 'The file upload has timed out.',
// Drawing & Images
'image_upload_error' => 'An error occurred uploading the image',
@@ -54,6 +53,7 @@ return [
// Attachments
'attachment_not_found' => 'Attachment not found',
'attachment_upload_error' => 'An error occurred uploading the attachment file',
// Pages
'page_draft_autosave_fail' => 'Failed to save draft. Ensure you have internet connection before saving this page',

View File

@@ -50,8 +50,8 @@ return [
// Color settings
'color_scheme' => 'Application Color Scheme',
'color_scheme_desc' => 'Set the colors to use in the BookStack interface. Colors can be configured separately for dark and light modes to best fit the theme and ensure legibility.',
'ui_colors_desc' => 'Set the primary color and default link color for BookStack. The primary color is mainly used for the header banner, buttons and interface decorations. The default link color is used for text-based links and actions, both within written content and in the Bookstack interface.',
'color_scheme_desc' => 'Set the colors to use in the application user interface. Colors can be configured separately for dark and light modes to best fit the theme and ensure legibility.',
'ui_colors_desc' => 'Set the application primary color and default link color. The primary color is mainly used for the header banner, buttons and interface decorations. The default link color is used for text-based links and actions, both within written content and in the application interface.',
'app_color' => 'Primary Color',
'link_color' => 'Default Link Color',
'content_colors_desc' => 'Set colors for all elements in the page organisation hierarchy. Choosing colors with a similar brightness to the default colors is recommended for readability.',

View File

@@ -6,6 +6,9 @@ return [
// Image Manager
'image_select' => 'Seleccionar Imagen',
'image_upload' => 'Subir imagen',
'image_intro' => 'Aquí puede seleccionar y administrar las imágenes que se han subido previamente al sistema.',
'image_intro_upload' => 'Suba una nueva imagen arrastrando un archivo de imagen en esta ventana, o usando el botón "Subir imagen" de arriba.',
'image_all' => 'Todas',
'image_all_title' => 'Ver todas las imágenes',
'image_book_title' => 'Ver las imágenes subidas a este libro',
@@ -18,12 +21,12 @@ return [
'image_delete_confirm_text' => '¿Estás seguro de que quieres eliminar esta imagen?',
'image_select_image' => 'Seleccionar Imagen',
'image_dropzone' => 'Arrastre las imágenes o hacer click aquí para Subir',
'image_dropzone_drop' => 'Arrastre las imágenes aquí para subirlas',
'images_deleted' => 'Imágenes borradas',
'image_preview' => 'Previsualización de la imagen',
'image_upload_success' => 'Imagen subida éxitosamente',
'image_update_success' => 'Detalles de la imagen actualizados exitosamente',
'image_delete_success' => 'Imagen borrada exitosamente',
'image_upload_remove' => 'Borrar',
// Code Editor
'code_editor' => 'Editar Código',

View File

@@ -311,12 +311,12 @@ return [
'attachments' => 'Adjuntos',
'attachments_explain' => 'Subir ficheros o agregar enlaces para mostrar en la página. Estos son visibles en la barra lateral de la página.',
'attachments_explain_instant_save' => 'Los cambios son guardados de manera instantánea .',
'attachments_items' => 'Elementos adjuntados',
'attachments_upload' => 'Subir Archivo',
'attachments_link' => 'Adjuntar Enlace',
'attachments_upload_drop' => 'También puedes arrastrar y soltar un archivo aquí para subirlo como un archivo adjunto.',
'attachments_set_link' => 'Ajustar Enlace',
'attachments_delete' => '¿Está seguro de que quiere eliminar este archivo adjunto?',
'attachments_dropzone' => 'Arrastre ficheros aquí o haga click aquí para adjuntar un fichero',
'attachments_dropzone' => 'Arrastre aquí archivos para subirlos',
'attachments_no_files' => 'No se han subido ficheros',
'attachments_explain_link' => 'Puede agregar un enlace si prefiere no subir un archivo. Puede ser un enlace a otra página o un enlace a un fichero en la nube.',
'attachments_link_name' => 'Nombre del Enlace',

View File

@@ -45,7 +45,6 @@ return [
'cannot_create_thumbs' => 'El servidor no puede crear la miniatura de la imagen. Compruebe que tiene la extensión PHP GD instalada.',
'server_upload_limit' => 'El servidor no permite la subida de ficheros de este tamaño. Intente subir un fichero de menor tamaño.',
'uploaded' => 'El servidor no permite la subida de ficheros de este tamaño. Intente subir un fichero de menor tamaño.',
'file_upload_timeout' => 'La carga del archivo ha caducado.',
// Drawing & Images
'image_upload_error' => 'Ha ocurrido un error al subir la imagen',
@@ -54,6 +53,7 @@ return [
// Attachments
'attachment_not_found' => 'No se encontró el adjunto',
'attachment_upload_error' => 'Ha ocurrido un error al subir el archivo adjunto',
// Pages
'page_draft_autosave_fail' => 'Fallo al guardar borrador. Asegúrese de que tiene conexión a Internet antes de guardar este borrador',

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