feat: news section

This commit is contained in:
saparatayev 2022-04-29 12:13:34 +05:00
parent 707be27d82
commit f1050363cf
91 changed files with 7618 additions and 3 deletions

1
plugins/rainlab/blog/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.DS_Store

View File

@ -0,0 +1,19 @@
# MIT license
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,172 @@
<?php namespace RainLab\Blog;
use Backend;
use Controller;
use RainLab\Blog\Models\Post;
use System\Classes\PluginBase;
use RainLab\Blog\Classes\TagProcessor;
use RainLab\Blog\Models\Category;
use Event;
class Plugin extends PluginBase
{
public function pluginDetails()
{
return [
'name' => 'rainlab.blog::lang.plugin.name',
'description' => 'rainlab.blog::lang.plugin.description',
'author' => 'Alexey Bobkov, Samuel Georges',
'icon' => 'icon-pencil',
'homepage' => 'https://github.com/rainlab/blog-plugin'
];
}
public function registerComponents()
{
return [
'RainLab\Blog\Components\Post' => 'blogPost',
'RainLab\Blog\Components\Posts' => 'blogPosts',
'RainLab\Blog\Components\Categories' => 'blogCategories',
'RainLab\Blog\Components\RssFeed' => 'blogRssFeed'
];
}
public function registerPermissions()
{
return [
'rainlab.blog.manage_settings' => [
'tab' => 'rainlab.blog::lang.blog.tab',
'label' => 'rainlab.blog::lang.blog.manage_settings'
],
'rainlab.blog.access_posts' => [
'tab' => 'rainlab.blog::lang.blog.tab',
'label' => 'rainlab.blog::lang.blog.access_posts'
],
'rainlab.blog.access_categories' => [
'tab' => 'rainlab.blog::lang.blog.tab',
'label' => 'rainlab.blog::lang.blog.access_categories'
],
'rainlab.blog.access_other_posts' => [
'tab' => 'rainlab.blog::lang.blog.tab',
'label' => 'rainlab.blog::lang.blog.access_other_posts'
],
'rainlab.blog.access_import_export' => [
'tab' => 'rainlab.blog::lang.blog.tab',
'label' => 'rainlab.blog::lang.blog.access_import_export'
],
'rainlab.blog.access_publish' => [
'tab' => 'rainlab.blog::lang.blog.tab',
'label' => 'rainlab.blog::lang.blog.access_publish'
]
];
}
public function registerNavigation()
{
return [
'blog' => [
'label' => 'rainlab.blog::lang.blog.menu_label',
'url' => Backend::url('rainlab/blog/posts'),
'icon' => 'icon-pencil',
'iconSvg' => 'plugins/rainlab/blog/assets/images/blog-icon.svg',
'permissions' => ['rainlab.blog.*'],
'order' => 300,
'sideMenu' => [
'new_post' => [
'label' => 'rainlab.blog::lang.posts.new_post',
'icon' => 'icon-plus',
'url' => Backend::url('rainlab/blog/posts/create'),
'permissions' => ['rainlab.blog.access_posts']
],
'posts' => [
'label' => 'rainlab.blog::lang.blog.posts',
'icon' => 'icon-copy',
'url' => Backend::url('rainlab/blog/posts'),
'permissions' => ['rainlab.blog.access_posts']
],
// 'categories' => [
// 'label' => 'rainlab.blog::lang.blog.categories',
// 'icon' => 'icon-list-ul',
// 'url' => Backend::url('rainlab/blog/categories'),
// 'permissions' => ['rainlab.blog.access_categories']
// ]
]
]
];
}
public function registerSettings()
{
return [
'blog' => [
'label' => 'rainlab.blog::lang.blog.menu_label',
'description' => 'rainlab.blog::lang.blog.settings_description',
'category' => 'rainlab.blog::lang.blog.menu_label',
'icon' => 'icon-pencil',
'class' => 'RainLab\Blog\Models\Settings',
'order' => 500,
'keywords' => 'blog post category',
'permissions' => ['rainlab.blog.manage_settings']
]
];
}
/**
* Register method, called when the plugin is first registered.
*/
public function register()
{
/*
* Register the image tag processing callback
*/
TagProcessor::instance()->registerCallback(function($input, $preview) {
if (!$preview) {
return $input;
}
return preg_replace('|\<img src="image" alt="([0-9]+)"([^>]*)\/>|m',
'<span class="image-placeholder" data-index="$1">
<span class="upload-dropzone">
<span class="label">Click or drop an image...</span>
<span class="indicator"></span>
</span>
</span>',
$input);
});
}
public function boot()
{
/*
* Register menu items for the RainLab.Pages plugin
*/
Event::listen('pages.menuitem.listTypes', function() {
return [
'blog-category' => 'rainlab.blog::lang.menuitem.blog_category',
'all-blog-categories' => 'rainlab.blog::lang.menuitem.all_blog_categories',
'blog-post' => 'rainlab.blog::lang.menuitem.blog_post',
'all-blog-posts' => 'rainlab.blog::lang.menuitem.all_blog_posts',
'category-blog-posts' => 'rainlab.blog::lang.menuitem.category_blog_posts',
];
});
Event::listen('pages.menuitem.getTypeInfo', function($type) {
if ($type == 'blog-category' || $type == 'all-blog-categories') {
return Category::getMenuTypeInfo($type);
}
elseif ($type == 'blog-post' || $type == 'all-blog-posts' || $type == 'category-blog-posts') {
return Post::getMenuTypeInfo($type);
}
});
Event::listen('pages.menuitem.resolveItem', function($type, $item, $url, $theme) {
if ($type == 'blog-category' || $type == 'all-blog-categories') {
return Category::resolveMenuItem($item, $url, $theme);
}
elseif ($type == 'blog-post' || $type == 'all-blog-posts' || $type == 'category-blog-posts') {
return Post::resolveMenuItem($item, $url, $theme);
}
});
}
}

View File

@ -0,0 +1,318 @@
# Blog Plugin
A simple, extensible blogging platform for October CMS.
[Blog & Forum Building Tutorial Video](https://player.vimeo.com/video/97088926)
## Editing posts
The plugin uses the markdown markup for the posts. You can use any Markdown syntax and some special tags for embedding images and videos (requires RainLab Blog Video plugin). To embed an image use the image placeholder:
![1](image)
The number in the first part is the placeholder index. If you use multiple images in a post you should use an unique index for each image:
![1](image)
![2](image)
You can also add classes or ids to images by using the [markdown extra](http://michelf.ca/projects/php-markdown/extra/) syntax:
![1](image){#id .class}
## Excerpt Vs. Read more
Posts are managed by selecting *Blog > Posts* from the menu. Each post can contain an excerpt by entering some text in this field on the *Manage* tab. This content is displayed on the page using the `summary` attribute of the blog post.
{{ post.summary|raw }}
Alternatively this field can be left blank and the excerpt can be captured from the main content (*Edit* tab). Use the special tag `<!-- more -->` to specify a summary from the main content, all content above this tag will be treated as the summary. For example:
This is a great introduction to a great blog post. This text is included as part of the excerpt / summary.
<!-- more -->
Let's dive in to more detail about why this post is so great. This text will not be included in the summary.
Finally, if no excerpt is specified and the "more" tag is not used, the blog post will capture the first 600 characters of the content and use this for the summary.
## Implementing front-end pages
The plugin provides several components for building the post list page (archive), category page, post details page and category list for the sidebar.
### Post list page
Use the `blogPosts` component to display a list of latest blog posts on a page. The component has the following properties:
* **pageNumber** - this value is used to determine what page the user is on, it should be a routing parameter for the default markup. The default value is **{{ :page }}** to obtain the value from the route parameter `:page`.
* **categoryFilter** - a category slug to filter the posts by. If left blank, all posts are displayed.
* **postsPerPage** - how many posts to display on a single page (the pagination is supported automatically). The default value is 10.
* **noPostsMessage** - message to display in the empty post list.
* **sortOrder** - the column name and direction used for the sort order of the posts. The default value is **published_at desc**.
* **categoryPage** - path to the category page. The default value is **blog/category** - it matches the pages/blog/category.htm file in the theme directory. This property is used in the default component partial for creating links to the blog categories.
* **postPage** - path to the post details page. The default value is **blog/post** - it matches the pages/blog/post.htm file in the theme directory. This property is used in the default component partial for creating links to the blog posts.
* **exceptPost** - ignore a single post by its slug or unique ID. The ignored post will not be included in the list, useful for showing other/related posts.
* **exceptCategories** - ignore posts from a comma-separated list of categories, given by their unique slug. The ignored posts will not be included in the list.
The blogPosts component injects the following variables to the page where it's used:
* **posts** - a list of blog posts loaded from the database.
* **postPage** - contains the value of the `postPage` component's property.
* **category** - the blog category object loaded from the database. If the category is not found, the variable value is **null**.
* **categoryPage** - contains the value of the `categoryPage` component's property.
* **noPostsMessage** - contains the value of the `noPostsMessage` component's property.
The component supports pagination and reads the current page index from the `:page` URL parameter. The next example shows the basic component usage on the blog home page:
title = "Blog"
url = "/blog/:page?"
[blogPosts]
postsPerPage = "5"
==
{% component 'blogPosts' %}
The next example shows the basic component usage with the category filter:
title = "Blog Category"
url = "/blog/category/:slug/:page?"
[blogPosts]
categoryFilter = "{{ :slug }}"
==
function onEnd()
{
// Optional - set the page title to the category name
if ($this->category)
$this->page->title = $this->category->name;
}
==
{% if not category %}
<h2>Category not found</h2>
{% else %}
<h2>{{ category.name }}</h2>
{% component 'blogPosts' %}
{% endif %}
The post list and the pagination are coded in the default component partial `plugins/rainlab/blog/components/posts/default.htm`. If the default markup is not suitable for your website, feel free to copy it from the default partial and replace the `{% component %}` call in the example above with the partial contents.
### Post page
Use the `blogPost` component to display a blog post on a page. The component has the following properties:
* **slug** - the value used for looking up the post by its slug. The default value is **{{ :slug }}** to obtain the value from the route parameter `:slug`.
* **categoryPage** - path to the category page. The default value is **blog/category** - it matches the pages/blog/category.htm file in the theme directory. This property is used in the default component partial for creating links to the blog categories.
The component injects the following variables to the page where it's used:
* **post** - the blog post object loaded from the database. If the post is not found, the variable value is **null**.
The next example shows the basic component usage on the blog page:
title = "Blog Post"
url = "/blog/post/:slug"
[blogPost]
==
<?php
function onEnd()
{
// Optional - set the page title to the post title
if ($this->post)
$this->page->title = $this->post->title;
}
?>
==
{% if post %}
<h2>{{ post.title }}</h2>
{% component 'blogPost' %}
{% else %}
<h2>Post not found</h2>
{% endif %}
The post details is coded in the default component partial `plugins/rainlab/blog/components/post/default.htm`.
### Category list
Use the `blogCategories` component to display a list of blog post categories with links. The component has the following properties:
* **slug** - the value used for looking up the current category by its slug. The default value is **{{ :slug }}** to obtain the value from the route parameter `:slug`.
* **displayEmpty** - determines if empty categories should be displayed. The default value is false.
* **categoryPage** - path to the category page. The default value is **blog/category** - it matches the pages/blog/category.htm file in the theme directory. This property is used in the default component partial for creating links to the blog categories.
The component injects the following variables to the page where it's used:
* **categoryPage** - contains the value of the `categoryPage` component's property.
* **categories** - a list of blog categories loaded from the database.
* **currentCategorySlug** - slug of the current category. This property is used for marking the current category in the category list.
The component can be used on any page. The next example shows the basic component usage on the blog home page:
title = "Blog"
url = "/blog/:page?"
[blogCategories]
==
...
<div class="sidebar">
{% component 'blogCategories' %}
</div>
...
The category list is coded in the default component partial `plugins/rainlab/blog/components/categories/default.htm`.
### RSS feed
Use the `blogRssFeed` component to display an RSS feed containing the latest blog posts. The following properties are supported:
* **categoryFilter** - a category slug to filter the posts by. If left blank, all posts are displayed.
* **postsPerPage** - how many posts to display on the feed. The default value is 10.
* **blogPage** - path to the main blog page. The default value is **blog** - it matches the pages/blog.htm file in the theme directory. This property is used in the RSS feed for creating links to the main blog page.
* **postPage** - path to the post details page. The default value is **blog/post** - it matches the pages/blog/post.htm file in the theme directory. This property is used in the RSS feed for creating links to the blog posts.
The component can be used on any page, it will hijack the entire page cycle to display the feed in RSS format. The next example shows how to use it:
title = "RSS Feed"
url = "/blog/rss.xml"
[blogRssFeed]
blogPage = "blog"
postPage = "blog/post"
==
<!-- This markup will never be displayed -->
## Configuration
To overwrite the default configuration create a `config/rainlab/blog/config.php`. You can return only values you want to override.
### Summary
A summary attribute is generated for each post.
If you enter an excerpt manually, it gets used as summary. Alternatively, you can use the `summary_separator` (default is `<!-- more -->`) to mark the end of the summary. If a post contains no separator, the text gets truncated after the number of characters specified in `summary_default_length` (default is 600 characters).
## Markdown guide
October supports [standard markdown syntax](http://daringfireball.net/projects/markdown/) as well as [extended markdown syntax](http://michelf.ca/projects/php-markdown/extra/)
### Classes and IDs
Classes and IDs can be added to images and other elements as shown below:
```
[link](url){#id .class}
![1](image){#id .class}
# October {#id .class}
```
### Fenced code blogs
Markdown extra makes it possible to use fenced code blocks. With fenced code blocks you do not need indentation on the areas you want to mark as code:
```
Code goes here
```
You can also use the `~` symbol:
~~~
Code goes here
~~~
### Tables
A *simple* table can be defined as follows:
```
First Header | Second Header
------------- | -------------
Content Cell | Content Cell
Content Cell | Content Cell
```
If you want to you can also add a leading and tailing pipe:
```
| First Header | Second Header |
| ------------- | ------------- |
| Content Cell | Content Cell |
| Content Cell | Content Cell |
```
To add alignment to the cells you simply need to add a `:` either at the start or end of a separator:
```
| First Header | Second Header |
| :------------ | ------------: |
| Content Cell | Content Cell |
| Content Cell | Content Cell |
```
To center align cell just add `:` on both sides:
```
| First Header | Second Header |
| ------------- | :-----------: |
| Content Cell | Content Cell |
| Content Cell | Content Cell |
```
### Definition lists
Below is an example of a simple definition list:
```
Laravel
: A popular PHP framework
October
: Awesome CMS built on Laravel
```
A term can also have multiple definitions:
```
Laravel
: A popular PHP framework
October
: Awesome CMS built on Laravel
: Supports markdown extra
```
You can also associate more than 1 term to a definition:
```
Laravel
October
: Built using PHP
```
### Footnotes
With markdown extra it is possible to create reference style footnotes:
```
This is some text with a footnote.[^1]
[^1]: And this is the footnote.
```
### Abbreviations
With markdown extra you can add abbreviations to your markup. The use this functionality first create a definition list:
```
*[HTML]: Hyper Text Markup Language
*[PHP]: Hypertext Preprocessor
```
Now markdown extra will convert all occurrences of `HTML` and `PHP` as follows:
```
<abbr title="Hyper Text Markup Language">HTML</abbr>
<abbr title="Hypertext Preprocessor">PHP</abbr>
```

View File

@ -0,0 +1,3 @@
.export-behavior .export-columns {
max-height: 450px !important;
}

View File

@ -0,0 +1,85 @@
.blog-post-preview .editor-preview .preview-content {
padding: 20px;
}
.blog-post-preview .editor-preview span.image-placeholder {
display: block;
}
.blog-post-preview .editor-preview span.image-placeholder .upload-dropzone {
background: #ecf0f1;
display: block;
border: 1px solid #e5e9ec;
padding: 25px;
min-height: 123px;
position: relative;
text-align: center;
cursor: pointer;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.blog-post-preview .editor-preview span.image-placeholder .upload-dropzone span.label {
color: #b1b9be;
font-size: 16px;
display: inline-block;
margin-top: 25px;
}
.blog-post-preview .editor-preview span.image-placeholder .upload-dropzone:before {
display: inline-block;
font-family: FontAwesome;
font-weight: normal;
font-style: normal;
text-decoration: inherit;
-webkit-font-smoothing: antialiased;
*margin-right: .3em;
content: "\f03e";
position: absolute;
left: 25px;
top: 25px;
line-height: 100%;
font-size: 73px;
color: #d1d3d4;
}
.blog-post-preview .editor-preview span.image-placeholder .upload-dropzone.hover,
.blog-post-preview .editor-preview span.image-placeholder .upload-dropzone:hover {
background: #2f99da;
}
.blog-post-preview .editor-preview span.image-placeholder .upload-dropzone.hover:before,
.blog-post-preview .editor-preview span.image-placeholder .upload-dropzone:hover:before,
.blog-post-preview .editor-preview span.image-placeholder .upload-dropzone.hover span.label,
.blog-post-preview .editor-preview span.image-placeholder .upload-dropzone:hover span.label {
color: white;
}
.blog-post-preview .editor-preview span.image-placeholder input[type=file] {
position: absolute;
left: -10000em;
}
.blog-post-preview-container .loading-indicator {
position: absolute;
display: none;
width: 20px;
height: 20px;
padding: 0!important;
background: transparent;
right: 10px;
left: auto;
top: 10px;
}
.blog-post-preview-container.loading-indicator-visible .loading-indicator {
display: block;
}
html.cssanimations .blog-post-preview span.image-placeholder.loading .upload-dropzone:before {
display: none;
}
html.cssanimations .blog-post-preview span.image-placeholder.loading .upload-dropzone .indicator {
display: block;
width: 50px;
height: 50px;
position: absolute;
left: 35px;
top: 35px;
background-image: url('../../../../../modules/system/assets/ui/images/loader-transparent.svg');
background-size: 50px 50px;
background-position: 50% 50%;
-webkit-animation: spin 1s linear infinite;
animation: spin 1s linear infinite;
}

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="64px" height="64px" viewBox="0 0 64 64" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<!-- Generator: Sketch 3.4.4 (17249) - http://www.bohemiancoding.com/sketch -->
<title>blog-icon</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
<g id="Group-+-Group" sketch:type="MSLayerGroup">
<g id="Group" sketch:type="MSShapeGroup">
<path d="M0.754,3.84 C0.754,1.719 2.473,0 4.594,0 L32.754,0 L48.754,13.44 L48.754,60.16 C48.754,62.281 47.035,64 44.914,64 L4.594,64 C2.473,64 0.754,62.281 0.754,60.16 L0.754,3.84 Z" id="Fill-392" fill="#FFFFFF"></path>
<path d="M32.754,0 L32.754,9.6 C32.754,11.721 34.473,13.44 36.594,13.44 L48.754,13.44 L32.754,0 Z" id="Fill-393" fill="#F0F1F1"></path>
<path d="M38.0416209,23 L12.3559338,23 C11.4141253,23 10.6435547,22.55 10.6435547,22 C10.6435547,21.45 11.4141253,21 12.3559338,21 L38.0416209,21 C38.9834294,21 39.754,21.45 39.754,22 C39.754,22.55 38.9834294,23 38.0416209,23 Z" id="Fill-397" fill="#E2E4E5"></path>
<path d="M29.4797252,27 C29.4797252,27.55 28.7091546,28 27.767346,28 L12.3559338,28 C11.4141253,28 10.6435547,27.55 10.6435547,27 C10.6435547,26.45 11.4141253,26 12.3559338,26 L27.767346,26 C28.7091546,26 29.4797252,26.45 29.4797252,27" id="Fill-398" fill="#E2E4E5"></path>
<path d="M23.767346,11 L12.3559338,11 C11.4141253,11 10.6435547,10.55 10.6435547,10 C10.6435547,9.45 11.4141253,9 12.3559338,9 L23.767346,9 C24.7091546,9 25.4797252,9.45 25.4797252,10 C25.4797252,10.55 24.7091546,11 23.767346,11 Z" id="Fill-398-Copy" fill="#E1332C"></path>
<path d="M39.754,35 C39.754,35.55 38.9834294,36 38.0416209,36 L12.3559338,36 C11.4141253,36 10.6435547,35.55 10.6435547,35 C10.6435547,34.45 11.4141253,34 12.3559338,34 L38.0416209,34 C38.9834294,34 39.754,34.45 39.754,35" id="Fill-399" fill="#E2E4E5"></path>
<path d="M29.4797252,40 C29.4797252,40.55 28.7091546,41 27.767346,41 L12.3559338,41 C11.4141253,41 10.6435547,40.55 10.6435547,40 C10.6435547,39.45 11.4141253,39 12.3559338,39 L27.767346,39 C28.7091546,39 29.4797252,39.45 29.4797252,40" id="Fill-400" fill="#E2E4E5"></path>
<path d="M39.754,48 C39.754,48.55 38.9834294,49 38.0416209,49 L12.3559338,49 C11.4141253,49 10.6435547,48.55 10.6435547,48 C10.6435547,47.45 11.4141253,47 12.3559338,47 L38.0416209,47 C38.9834294,47 39.754,47.45 39.754,48" id="Fill-401" fill="#E2E4E5"></path>
<path d="M29.4797252,53 C29.4797252,53.55 28.7091546,54 27.767346,54 L12.3559338,54 C11.4141253,54 10.6435547,53.55 10.6435547,53 C10.6435547,52.45 11.4141253,52 12.3559338,52 L27.767346,52 C28.7091546,52 29.4797252,52.45 29.4797252,53" id="Fill-402" fill="#E2E4E5"></path>
</g>
<g id="Group" transform="translate(27.000000, 16.000000)" sketch:type="MSShapeGroup">
<path d="M31.8979,11.4983 L10.6949,35.4653 L4.8179,36.6753 C4.6479,35.8573 4.2249,35.0823 3.5509,34.4863 C2.8769,33.8893 2.0559,33.5643 1.2229,33.4953 L1.7069,27.5143 L22.9099,3.5473 L31.8979,11.4983 Z" id="Fill-647" fill="#F4D0A1"></path>
<path d="M31.8692,11.4729 C31.8852,11.4869 11.1512,34.9499 11.1512,34.9499 C11.7392,33.7029 11.5032,32.1759 10.4362,31.2309 C9.3092,30.2349 7.6512,30.2359 6.5312,31.1689 C7.2692,29.8979 7.0682,28.2519 5.9422,27.2549 C4.8622,26.3009 3.2942,26.2619 2.1802,27.0819 C2.1442,27.1089 22.8852,3.5759 22.8852,3.5759 C22.8992,3.5599 31.8692,11.4729 31.8692,11.4729 Z" id="Fill-648" fill="#FC5B55"></path>
<path d="M31.8979,11.4983 L22.9099,3.5473 L24.2349,2.0493 L33.2229,10.0003 L31.8979,11.4983 Z" id="Fill-649" fill="#FACB1B"></path>
<path d="M32.7497,1.5706 L32.6597,1.4916 C30.2027,-0.6824 26.4487,-0.4524 24.2747,2.0046 L24.2357,2.0496 L33.2227,10.0006 L33.2627,9.9556 C35.4367,7.4986 35.2067,3.7446 32.7497,1.5706" id="Fill-650" fill="#F89392"></path>
<path d="M11.1258,34.9796 C11.7438,33.7326 11.5138,32.1846 10.4358,31.2306 C9.3118,30.2366 7.6588,30.2356 6.5388,31.1626 C6.5198,31.1786 27.3788,7.5516 27.3788,7.5516 C27.3928,7.5356 31.8698,11.4736 31.8698,11.4736 C31.8848,11.4866 11.1258,34.9796 11.1258,34.9796 Z" id="Fill-651" fill="#E1332C"></path>
<path d="M4.8181,36.6754 L0.9001,37.4824 L1.2231,33.4954 C2.0561,33.5644 2.8771,33.8894 3.5511,34.4864 C4.2251,35.0824 4.6481,35.8574 4.8181,36.6754" id="Fill-652" fill="#3E3E3F"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@ -0,0 +1,184 @@
+function ($) { "use strict";
var PostForm = function () {
this.$form = $('#post-form')
this.$markdownEditor = $('[data-field-name=content] [data-control=markdowneditor]:first', this.$form)
this.$preview = $('.editor-preview', this.$markdownEditor)
this.formAction = this.$form.attr('action')
this.sessionKey = $('input[name=_session_key]', this.$form).val()
if (this.$markdownEditor.length > 0) {
this.codeEditor = this.$markdownEditor.markdownEditor('getEditorObject')
this.$markdownEditor.on('initPreview.oc.markdowneditor', $.proxy(this.initPreview, this))
this.initDropzones()
this.initFormEvents()
this.addToolbarButton()
}
this.initLayout()
}
PostForm.prototype.addToolbarButton = function() {
this.buttonClickCount = 1
var self = this,
$button = this.$markdownEditor.markdownEditor('findToolbarButton', 'image')
if (!$button.length) return
$button.data('button-action', 'insertLine')
$button.data('button-template', '\n\n![1](image)\n')
$button.on('click', function() {
$button.data('button-template', '\n\n!['+self.buttonClickCount+'](image)\n')
self.buttonClickCount++
})
}
PostForm.prototype.initPreview = function() {
this.initImageUploaders()
}
PostForm.prototype.updateScroll = function() {
// Reserved in case MarkdownEditor uses scrollbar plugin
// this.$preview.data('oc.scrollbar').update()
}
PostForm.prototype.initImageUploaders = function() {
var self = this
$('span.image-placeholder .upload-dropzone', this.$preview).each(function(){
var
$placeholder = $(this).parent(),
$link = $('span.label', $placeholder),
placeholderIndex = $placeholder.data('index')
var uploaderOptions = {
url: self.formAction,
clickable: [$(this).get(0), $link.get(0)],
previewsContainer: $('<div />').get(0),
paramName: 'file',
headers: {}
}
/*
* Add CSRF token to headers
*/
var token = $('meta[name="csrf-token"]').attr('content')
if (token) {
uploaderOptions.headers['X-CSRF-TOKEN'] = token
}
var dropzone = new Dropzone($(this).get(0), uploaderOptions)
dropzone.on('error', function(file, error) {
alert('Error uploading file: ' + error)
})
dropzone.on('success', function(file, data){
if (data.error)
alert(data.error)
else {
self.pauseUpdates()
var $img = $('<img src="'+data.path+'">')
$img.load(function(){
self.updateScroll()
})
$placeholder.replaceWith($img)
self.codeEditor.replace('!['+data.file+']('+data.path+')', {
needle: '!['+placeholderIndex+'](image)'
})
self.resumeUpdates()
}
})
dropzone.on('complete', function(){
$placeholder.removeClass('loading')
})
dropzone.on('sending', function(file, xhr, formData) {
formData.append('X_BLOG_IMAGE_UPLOAD', 1)
formData.append('_session_key', self.sessionKey)
$placeholder.addClass('loading')
})
})
}
PostForm.prototype.pauseUpdates = function() {
this.$markdownEditor.markdownEditor('pauseUpdates')
}
PostForm.prototype.resumeUpdates = function() {
this.$markdownEditor.markdownEditor('resumeUpdates')
}
PostForm.prototype.initDropzones = function() {
$(document).bind('dragover', function (e) {
var dropZone = $('span.image-placeholder .upload-dropzone'),
foundDropzone,
timeout = window.dropZoneTimeout
if (!timeout)
dropZone.addClass('in');
else
clearTimeout(timeout);
var found = false,
node = e.target
do {
if ($(node).hasClass('dropzone')) {
found = true
foundDropzone = $(node)
break
}
node = node.parentNode;
} while (node != null);
dropZone.removeClass('in hover')
if (found)
foundDropzone.addClass('hover')
window.dropZoneTimeout = setTimeout(function () {
window.dropZoneTimeout = null
dropZone.removeClass('in hover')
}, 100)
})
}
PostForm.prototype.initFormEvents = function() {
$(document).on('ajaxSuccess', '#post-form', function(event, context, data){
if (context.handler == 'onSave' && !data.X_OCTOBER_ERROR_FIELDS) {
$(this).trigger('unchange.oc.changeMonitor')
}
})
}
PostForm.prototype.initLayout = function() {
$('#Form-secondaryTabs .tab-pane.layout-cell:not(:first-child)').addClass('padded-pane')
}
PostForm.prototype.replacePlaceholder = function(placeholder, placeholderHtmlReplacement, mdCodePlaceholder, mdCodeReplacement) {
this.pauseUpdates()
placeholder.replaceWith(placeholderHtmlReplacement)
this.codeEditor.replace(mdCodeReplacement, {
needle: mdCodePlaceholder
})
this.updateScroll()
this.resumeUpdates()
}
$(document).ready(function(){
var form = new PostForm()
if ($.oc === undefined)
$.oc = {}
$.oc.blogPostForm = form
})
}(window.jQuery);

View File

@ -0,0 +1,99 @@
@import "../../../../../modules/backend/assets/less/core/boot.less";
.blog-post-preview .editor-preview {
.preview-content {
padding: 20px;
}
span.image-placeholder {
display: block;
.upload-dropzone {
background: #ecf0f1;
display: block;
border: 1px solid #e5e9ec;
padding: 25px;
min-height: 123px;
position: relative;
text-align: center;
cursor: pointer;
.box-sizing(border-box);
span.label {
color: #b1b9be;
font-size: 16px;
display: inline-block;
margin-top: 25px;
}
&:before {
display: inline-block;
.icon(@picture-o);
position: absolute;
left: 25px;
top: 25px;
line-height: 100%;
font-size: 73px;
color: #d1d3d4;
}
&.hover, &:hover {
background: #2f99da;
&:before, span.label {
color: white;
}
}
}
input[type=file] {
position: absolute;
left: -10000em;
}
}
}
.blog-post-preview-container {
.loading-indicator {
position: absolute;
display: none;
width: 20px;
height: 20px;
padding: 0!important;
background: transparent;
right: 10px;
left: auto;
top: 10px;
}
&.loading-indicator-visible {
.loading-indicator {
display: block;
}
}
}
html.cssanimations {
.blog-post-preview {
span.image-placeholder.loading {
.upload-dropzone {
&:before {
display: none;
}
.indicator {
display: block;
width: 50px;
height: 50px;
position: absolute;
left: 35px;
top: 35px;
background-image:url('../../../../../modules/system/assets/ui/images/loader-transparent.svg');
background-size: 50px 50px;
background-position: 50% 50%;
.animation(spin 1s linear infinite);
}
}
}
}
}

View File

@ -0,0 +1,39 @@
<?php namespace RainLab\Blog\Classes;
/**
* Blog Markdown tag processor.
*
* @package rainlab\blog
* @author Alexey Bobkov, Samuel Georges
*/
class TagProcessor
{
use \October\Rain\Support\Traits\Singleton;
/**
* @var array Cache of processing callbacks.
*/
private $callbacks = [];
/**
* Registers a callback function that handles blog post markup.
* The callback function should accept two arguments - the HTML string
* generated from Markdown contents and the preview flag determining whether
* the function should return a markup for the blog post preview form or for the
* front-end.
* @param callable $callback A callable function.
*/
public function registerCallback(callable $callback)
{
$this->callbacks[] = $callback;
}
public function processTags($markup, $preview)
{
foreach ($this->callbacks as $callback) {
$markup = $callback($markup, $preview);
}
return $markup;
}
}

View File

@ -0,0 +1,113 @@
<?php namespace RainLab\Blog\Components;
use Db;
use Carbon\Carbon;
use Cms\Classes\Page;
use Cms\Classes\ComponentBase;
use RainLab\Blog\Models\Category as BlogCategory;
class Categories extends ComponentBase
{
/**
* @var Collection A collection of categories to display
*/
public $categories;
/**
* @var string Reference to the page name for linking to categories.
*/
public $categoryPage;
/**
* @var string Reference to the current category slug.
*/
public $currentCategorySlug;
public function componentDetails()
{
return [
'name' => 'rainlab.blog::lang.settings.category_title',
'description' => 'rainlab.blog::lang.settings.category_description'
];
}
public function defineProperties()
{
return [
'slug' => [
'title' => 'rainlab.blog::lang.settings.category_slug',
'description' => 'rainlab.blog::lang.settings.category_slug_description',
'default' => '{{ :slug }}',
'type' => 'string',
],
'displayEmpty' => [
'title' => 'rainlab.blog::lang.settings.category_display_empty',
'description' => 'rainlab.blog::lang.settings.category_display_empty_description',
'type' => 'checkbox',
'default' => 0,
],
'categoryPage' => [
'title' => 'rainlab.blog::lang.settings.category_page',
'description' => 'rainlab.blog::lang.settings.category_page_description',
'type' => 'dropdown',
'default' => 'blog/category',
'group' => 'rainlab.blog::lang.settings.group_links',
],
];
}
public function getCategoryPageOptions()
{
return Page::sortBy('baseFileName')->lists('baseFileName', 'baseFileName');
}
public function onRun()
{
$this->currentCategorySlug = $this->page['currentCategorySlug'] = $this->property('slug');
$this->categoryPage = $this->page['categoryPage'] = $this->property('categoryPage');
$this->categories = $this->page['categories'] = $this->loadCategories();
}
/**
* Load all categories or, depending on the <displayEmpty> option, only those that have blog posts
* @return mixed
*/
protected function loadCategories()
{
$categories = BlogCategory::with('posts_count')->getNested();
if (!$this->property('displayEmpty')) {
$iterator = function ($categories) use (&$iterator) {
return $categories->reject(function ($category) use (&$iterator) {
if ($category->getNestedPostCount() == 0) {
return true;
}
if ($category->children) {
$category->children = $iterator($category->children);
}
return false;
});
};
$categories = $iterator($categories);
}
/*
* Add a "url" helper attribute for linking to each category
*/
return $this->linkCategories($categories);
}
/**
* Sets the URL on each category according to the defined category page
* @return void
*/
protected function linkCategories($categories)
{
return $categories->each(function ($category) {
$category->setUrl($this->categoryPage, $this->controller);
if ($category->children) {
$this->linkCategories($category->children);
}
});
}
}

View File

@ -0,0 +1,162 @@
<?php namespace RainLab\Blog\Components;
use Event;
use BackendAuth;
use Cms\Classes\Page;
use Cms\Classes\ComponentBase;
use RainLab\Blog\Models\Post as BlogPost;
class Post extends ComponentBase
{
/**
* @var RainLab\Blog\Models\Post The post model used for display.
*/
public $post;
/**
* @var string Reference to the page name for linking to categories.
*/
public $categoryPage;
public function componentDetails()
{
return [
'name' => 'rainlab.blog::lang.settings.post_title',
'description' => 'rainlab.blog::lang.settings.post_description'
];
}
public function defineProperties()
{
return [
'slug' => [
'title' => 'rainlab.blog::lang.settings.post_slug',
'description' => 'rainlab.blog::lang.settings.post_slug_description',
'default' => '{{ :slug }}',
'type' => 'string',
],
'id' => [
'title' => 'Post ID',
'description' => 'Post ID',
'default' => '{{ :id }}',
'type' => 'string',
],
'categoryPage' => [
'title' => 'rainlab.blog::lang.settings.post_category',
'description' => 'rainlab.blog::lang.settings.post_category_description',
'type' => 'dropdown',
'default' => 'blog/category',
],
];
}
public function getCategoryPageOptions()
{
return Page::sortBy('baseFileName')->lists('baseFileName', 'baseFileName');
}
public function init()
{
Event::listen('translate.localePicker.translateParams', function ($page, $params, $oldLocale, $newLocale) {
$newParams = $params;
if (isset($params['slug'])) {
$records = BlogPost::transWhere('slug', $params['slug'], $oldLocale)->first();
if ($records) {
$records->translateContext($newLocale);
$newParams['slug'] = $records['slug'];
}
}
return $newParams;
});
}
public function onRun()
{
$this->categoryPage = $this->page['categoryPage'] = $this->property('categoryPage');
$this->post = $this->page['post'] = $this->loadPost();
if (!$this->post) {
$this->setStatusCode(404);
return $this->controller->run('404');
}
}
public function onRender()
{
if (empty($this->post)) {
$this->post = $this->page['post'] = $this->loadPost();
}
}
protected function loadPost()
{
$slug = $this->property('slug');
$post = new BlogPost;
$query = $post->query();
if ($post->isClassExtendedWith('RainLab.Translate.Behaviors.TranslatableModel')) {
$query->transWhere('slug', $slug);
} else {
$query->where('slug', $slug);
}
if (!$this->checkEditor()) {
$query->isPublished();
}
$post = $query->first();
/*
* Add a "url" helper attribute for linking to each category
*/
if ($post && $post->exists && $post->categories->count()) {
$post->categories->each(function($category) {
$category->setUrl($this->categoryPage, $this->controller);
});
}
return $post;
}
public function previousPost()
{
return $this->getPostSibling(-1);
}
public function nextPost()
{
return $this->getPostSibling(1);
}
protected function getPostSibling($direction = 1)
{
if (!$this->post) {
return;
}
$method = $direction === -1 ? 'previousPost' : 'nextPost';
if (!$post = $this->post->$method()) {
return;
}
$postPage = $this->getPage()->getBaseFileName();
$post->setUrl($postPage, $this->controller);
$post->categories->each(function($category) {
$category->setUrl($this->categoryPage, $this->controller);
});
return $post;
}
protected function checkEditor()
{
$backendUser = BackendAuth::getUser();
return $backendUser && $backendUser->hasAccess('rainlab.blog.access_posts');
}
}

View File

@ -0,0 +1,257 @@
<?php namespace RainLab\Blog\Components;
use Lang;
use Redirect;
use BackendAuth;
use Cms\Classes\Page;
use Cms\Classes\ComponentBase;
use October\Rain\Database\Model;
use October\Rain\Database\Collection;
use RainLab\Blog\Models\Post as BlogPost;
use RainLab\Blog\Models\Category as BlogCategory;
use RainLab\Blog\Models\Settings as BlogSettings;
class Posts extends ComponentBase
{
/**
* A collection of posts to display
*
* @var Collection
*/
public $posts;
/**
* Parameter to use for the page number
*
* @var string
*/
public $pageParam;
/**
* If the post list should be filtered by a category, the model to use
*
* @var Model
*/
public $category;
/**
* Message to display when there are no messages
*
* @var string
*/
public $noPostsMessage;
/**
* Reference to the page name for linking to posts
*
* @var string
*/
public $postPage;
/**
* Reference to the page name for linking to categories
*
* @var string
*/
public $categoryPage;
/**
* If the post list should be ordered by another attribute
*
* @var string
*/
public $sortOrder;
public function componentDetails()
{
return [
'name' => 'rainlab.blog::lang.settings.posts_title',
'description' => 'rainlab.blog::lang.settings.posts_description'
];
}
public function defineProperties()
{
return [
'pageNumber' => [
'title' => 'rainlab.blog::lang.settings.posts_pagination',
'description' => 'rainlab.blog::lang.settings.posts_pagination_description',
'type' => 'string',
'default' => '{{ :page }}',
],
'categoryFilter' => [
'title' => 'rainlab.blog::lang.settings.posts_filter',
'description' => 'rainlab.blog::lang.settings.posts_filter_description',
'type' => 'string',
'default' => '',
],
'postsPerPage' => [
'title' => 'rainlab.blog::lang.settings.posts_per_page',
'type' => 'string',
'validationPattern' => '^[0-9]+$',
'validationMessage' => 'rainlab.blog::lang.settings.posts_per_page_validation',
'default' => '10',
],
'noPostsMessage' => [
'title' => 'rainlab.blog::lang.settings.posts_no_posts',
'description' => 'rainlab.blog::lang.settings.posts_no_posts_description',
'type' => 'string',
'default' => Lang::get('rainlab.blog::lang.settings.posts_no_posts_default'),
'showExternalParam' => false,
],
'sortOrder' => [
'title' => 'rainlab.blog::lang.settings.posts_order',
'description' => 'rainlab.blog::lang.settings.posts_order_description',
'type' => 'dropdown',
'default' => 'published_at desc',
],
'categoryPage' => [
'title' => 'rainlab.blog::lang.settings.posts_category',
'description' => 'rainlab.blog::lang.settings.posts_category_description',
'type' => 'dropdown',
'default' => 'blog/category',
'group' => 'rainlab.blog::lang.settings.group_links',
],
'postPage' => [
'title' => 'rainlab.blog::lang.settings.posts_post',
'description' => 'rainlab.blog::lang.settings.posts_post_description',
'type' => 'dropdown',
'default' => 'blog/post',
'group' => 'rainlab.blog::lang.settings.group_links',
],
'exceptPost' => [
'title' => 'rainlab.blog::lang.settings.posts_except_post',
'description' => 'rainlab.blog::lang.settings.posts_except_post_description',
'type' => 'string',
'validationPattern' => '^[a-z0-9\-_,\s]+$',
'validationMessage' => 'rainlab.blog::lang.settings.posts_except_post_validation',
'default' => '',
'group' => 'rainlab.blog::lang.settings.group_exceptions',
],
'exceptCategories' => [
'title' => 'rainlab.blog::lang.settings.posts_except_categories',
'description' => 'rainlab.blog::lang.settings.posts_except_categories_description',
'type' => 'string',
'validationPattern' => '^[a-z0-9\-_,\s]+$',
'validationMessage' => 'rainlab.blog::lang.settings.posts_except_categories_validation',
'default' => '',
'group' => 'rainlab.blog::lang.settings.group_exceptions',
],
];
}
public function getCategoryPageOptions()
{
return Page::sortBy('baseFileName')->lists('baseFileName', 'baseFileName');
}
public function getPostPageOptions()
{
return Page::sortBy('baseFileName')->lists('baseFileName', 'baseFileName');
}
public function getSortOrderOptions()
{
$options = BlogPost::$allowedSortingOptions;
foreach ($options as $key => $value) {
$options[$key] = Lang::get($value);
}
return $options;
}
public function onRun()
{
$this->prepareVars();
$this->category = $this->page['category'] = $this->loadCategory();
$this->posts = $this->page['posts'] = $this->listPosts();
/*
* If the page number is not valid, redirect
*/
if ($pageNumberParam = $this->paramName('pageNumber')) {
$currentPage = $this->property('pageNumber');
if ($currentPage > ($lastPage = $this->posts->lastPage()) && $currentPage > 1) {
return Redirect::to($this->currentPageUrl([$pageNumberParam => $lastPage]));
}
}
}
protected function prepareVars()
{
$this->pageParam = $this->page['pageParam'] = $this->paramName('pageNumber');
$this->noPostsMessage = $this->page['noPostsMessage'] = $this->property('noPostsMessage');
/*
* Page links
*/
$this->postPage = $this->page['postPage'] = $this->property('postPage');
$this->categoryPage = $this->page['categoryPage'] = $this->property('categoryPage');
}
protected function listPosts()
{
$category = $this->category ? $this->category->id : null;
$categorySlug = $this->category ? $this->category->slug : null;
/*
* List all the posts, eager load their categories
*/
$isPublished = !$this->checkEditor();
$posts = BlogPost::with(['categories', 'featured_images'])->listFrontEnd([
'page' => $this->property('pageNumber'),
'sort' => $this->property('sortOrder'),
'perPage' => $this->property('postsPerPage'),
'search' => trim(input('search')),
'category' => $category,
'published' => $isPublished,
'exceptPost' => is_array($this->property('exceptPost'))
? $this->property('exceptPost')
: preg_split('/,\s*/', $this->property('exceptPost'), -1, PREG_SPLIT_NO_EMPTY),
'exceptCategories' => is_array($this->property('exceptCategories'))
? $this->property('exceptCategories')
: preg_split('/,\s*/', $this->property('exceptCategories'), -1, PREG_SPLIT_NO_EMPTY),
]);
/*
* Add a "url" helper attribute for linking to each post and category
*/
$posts->each(function($post) use ($categorySlug) {
$post->setUrl($this->postPage, $this->controller, ['category' => $categorySlug]);
$post->categories->each(function($category) {
$category->setUrl($this->categoryPage, $this->controller);
});
});
return $posts;
}
protected function loadCategory()
{
if (!$slug = $this->property('categoryFilter')) {
return null;
}
$category = new BlogCategory;
$category = $category->isClassExtendedWith('RainLab.Translate.Behaviors.TranslatableModel')
? $category->transWhere('slug', $slug)
: $category->where('slug', $slug);
$category = $category->first();
return $category ?: null;
}
protected function checkEditor()
{
$backendUser = BackendAuth::getUser();
return $backendUser && $backendUser->hasAccess('rainlab.blog.access_posts') && BlogSettings::get('show_all_posts', true);
}
}

View File

@ -0,0 +1,159 @@
<?php namespace RainLab\Blog\Components;
use Lang;
use Response;
use Cms\Classes\Page;
use Cms\Classes\ComponentBase;
use RainLab\Blog\Models\Post as BlogPost;
use RainLab\Blog\Models\Category as BlogCategory;
class RssFeed extends ComponentBase
{
/**
* A collection of posts to display
* @var Collection
*/
public $posts;
/**
* If the post list should be filtered by a category, the model to use.
* @var Model
*/
public $category;
/**
* Reference to the page name for the main blog page.
* @var string
*/
public $blogPage;
/**
* Reference to the page name for linking to posts.
* @var string
*/
public $postPage;
public function componentDetails()
{
return [
'name' => 'rainlab.blog::lang.settings.rssfeed_title',
'description' => 'rainlab.blog::lang.settings.rssfeed_description'
];
}
public function defineProperties()
{
return [
'categoryFilter' => [
'title' => 'rainlab.blog::lang.settings.posts_filter',
'description' => 'rainlab.blog::lang.settings.posts_filter_description',
'type' => 'string',
'default' => '',
],
'sortOrder' => [
'title' => 'rainlab.blog::lang.settings.posts_order',
'description' => 'rainlab.blog::lang.settings.posts_order_description',
'type' => 'dropdown',
'default' => 'created_at desc',
],
'postsPerPage' => [
'title' => 'rainlab.blog::lang.settings.posts_per_page',
'type' => 'string',
'validationPattern' => '^[0-9]+$',
'validationMessage' => 'rainlab.blog::lang.settings.posts_per_page_validation',
'default' => '10',
],
'blogPage' => [
'title' => 'rainlab.blog::lang.settings.rssfeed_blog',
'description' => 'rainlab.blog::lang.settings.rssfeed_blog_description',
'type' => 'dropdown',
'default' => 'blog/post',
'group' => 'rainlab.blog::lang.settings.group_links',
],
'postPage' => [
'title' => 'rainlab.blog::lang.settings.posts_post',
'description' => 'rainlab.blog::lang.settings.posts_post_description',
'type' => 'dropdown',
'default' => 'blog/post',
'group' => 'rainlab.blog::lang.settings.group_links',
],
];
}
public function getBlogPageOptions()
{
return Page::sortBy('baseFileName')->lists('baseFileName', 'baseFileName');
}
public function getPostPageOptions()
{
return Page::sortBy('baseFileName')->lists('baseFileName', 'baseFileName');
}
public function getSortOrderOptions()
{
$options = BlogPost::$allowedSortingOptions;
foreach ($options as $key => $value) {
$options[$key] = Lang::get($value);
}
return $options;
}
public function onRun()
{
$this->prepareVars();
$xmlFeed = $this->renderPartial('@default');
return Response::make($xmlFeed, '200')->header('Content-Type', 'text/xml');
}
protected function prepareVars()
{
$this->blogPage = $this->page['blogPage'] = $this->property('blogPage');
$this->postPage = $this->page['postPage'] = $this->property('postPage');
$this->category = $this->page['category'] = $this->loadCategory();
$this->posts = $this->page['posts'] = $this->listPosts();
$this->page['link'] = $this->pageUrl($this->blogPage);
$this->page['rssLink'] = $this->currentPageUrl();
}
protected function listPosts()
{
$category = $this->category ? $this->category->id : null;
/*
* List all the posts, eager load their categories
*/
$posts = BlogPost::with('categories')->listFrontEnd([
'sort' => $this->property('sortOrder'),
'perPage' => $this->property('postsPerPage'),
'category' => $category
]);
/*
* Add a "url" helper attribute for linking to each post and category
*/
$posts->each(function($post) {
$post->setUrl($this->postPage, $this->controller);
});
return $posts;
}
protected function loadCategory()
{
if (!$categoryId = $this->property('categoryFilter')) {
return null;
}
if (!$category = BlogCategory::whereSlug($categoryId)->first()) {
return null;
}
return $category;
}
}

View File

@ -0,0 +1,10 @@
{% if __SELF__.categories|length > 0 %}
<ul class="category-list">
{% partial __SELF__ ~ "::items"
categories = __SELF__.categories
currentCategorySlug = __SELF__.currentCategorySlug
%}
</ul>
{% else %}
<p>No categories were found.</p>
{% endif %}

View File

@ -0,0 +1,18 @@
{% for category in categories %}
{% set postCount = category.post_count %}
<li {% if category.slug == currentCategorySlug %}class="active"{% endif %}>
<a href="{{ category.url }}">{{ category.name }}</a>
{% if postCount %}
<span class="badge">{{ postCount }}</span>
{% endif %}
{% if category.children|length > 0 %}
<ul>
{% partial __SELF__ ~ "::items"
categories=category.children
currentCategorySlug=currentCategorySlug
%}
</ul>
{% endif %}
</li>
{% endfor %}

View File

@ -0,0 +1,27 @@
{% set post = __SELF__.post %}
<div class="content">{{ post.content_html|raw }}</div>
{% if post.featured_images.count %}
<div class="featured-images text-center">
{% for image in post.featured_images %}
<p>
<img
data-src="{{ image.filename }}"
src="{{ image.path }}"
alt="{{ image.description }}"
style="max-width: 100%" />
</p>
{% endfor %}
</div>
{% endif %}
<p class="info">
Posted
{% if post.categories.count %} in
{% for category in post.categories %}
<a href="{{ category.url }}">{{ category.name }}</a>{% if not loop.last %}, {% endif %}
{% endfor %}
{% endif %}
on {{ post.published_at|date('M d, Y') }}
</p>

View File

@ -0,0 +1,40 @@
{% set posts = __SELF__.posts %}
<ul class="post-list">
{% for post in posts %}
<li>
<h3><a href="{{ post.url }}">{{ post.title }}</a></h3>
<p class="info">
Posted
{% if post.categories.count %} in {% endif %}
{% for category in post.categories %}
<a href="{{ category.url }}">{{ category.name }}</a>{% if not loop.last %}, {% endif %}
{% endfor %}
on {{ post.published_at|date('M d, Y') }}
</p>
<p class="excerpt">{{ post.summary|raw }}</p>
</li>
{% else %}
<li class="no-data">{{ __SELF__.noPostsMessage }}</li>
{% endfor %}
</ul>
{% if posts.lastPage > 1 %}
<ul class="pagination">
{% if posts.currentPage > 1 %}
<li><a href="{{ this.page.baseFileName|page({ (__SELF__.pageParam): (posts.currentPage-1) }) }}">&larr; Prev</a></li>
{% endif %}
{% for page in 1..posts.lastPage %}
<li class="{{ posts.currentPage == page ? 'active' : null }}">
<a href="{{ this.page.baseFileName|page({ (__SELF__.pageParam): page }) }}">{{ page }}</a>
</li>
{% endfor %}
{% if posts.lastPage > posts.currentPage %}
<li><a href="{{ this.page.baseFileName|page({ (__SELF__.pageParam): (posts.currentPage+1) }) }}">Next &rarr;</a></li>
{% endif %}
</ul>
{% endif %}

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>{{ this.page.meta_title ?: this.page.title }}</title>
<link>{{ link }}</link>
<description>{{ this.page.meta_description ?: this.page.description }}</description>
<atom:link href="{{ rssLink }}" rel="self" type="application/rss+xml" />
{% for post in posts %}
<item>
<title>{{ post.title }}</title>
<link>{{ post.url }}</link>
<guid>{{ post.url }}</guid>
<pubDate>{{ post.published_at.toRfc2822String }}</pubDate>
<description>{{ post.summary }}</description>
</item>
{% endfor %}
</channel>
</rss>

View File

@ -0,0 +1,25 @@
{
"name": "rainlab/blog-plugin",
"type": "october-plugin",
"description": "Blog plugin for October CMS",
"homepage": "https://octobercms.com/plugin/rainlab-blog",
"keywords": ["october", "octobercms", "blog"],
"license": "MIT",
"authors": [
{
"name": "Alexey Bobkov",
"email": "aleksey.bobkov@gmail.com",
"role": "Co-founder"
},
{
"name": "Samuel Georges",
"email": "daftspunky@gmail.com",
"role": "Co-founder"
}
],
"require": {
"php": ">=7.0",
"composer/installers": "~1.0"
},
"minimum-stability": "dev"
}

View File

@ -0,0 +1,18 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Summary Config
|--------------------------------------------------------------------------
|
| Specify a custom tag and length for blog post summaries
|
*/
'summary_separator' => '<!-- more -->',
'summary_default_length' => 600
];

View File

@ -0,0 +1,47 @@
<?php namespace RainLab\Blog\Controllers;
use BackendMenu;
use Flash;
use Lang;
use Backend\Classes\Controller;
use RainLab\Blog\Models\Category;
class Categories extends Controller
{
public $implement = [
\Backend\Behaviors\FormController::class,
\Backend\Behaviors\ListController::class,
\Backend\Behaviors\ReorderController::class
];
public $formConfig = 'config_form.yaml';
public $listConfig = 'config_list.yaml';
public $reorderConfig = 'config_reorder.yaml';
public $requiredPermissions = ['rainlab.blog.access_categories'];
public function __construct()
{
parent::__construct();
BackendMenu::setContext('RainLab.Blog', 'blog', 'categories');
}
public function index_onDelete()
{
if (($checkedIds = post('checked')) && is_array($checkedIds) && count($checkedIds)) {
foreach ($checkedIds as $categoryId) {
if ((!$category = Category::find($categoryId))) {
continue;
}
$category->delete();
}
Flash::success(Lang::get('rainlab.blog::lang.category.delete_success'));
}
return $this->listRefresh();
}
}

View File

@ -0,0 +1,134 @@
<?php namespace RainLab\Blog\Controllers;
use BackendMenu;
use Flash;
use Lang;
use Backend\Classes\Controller;
use RainLab\Blog\Models\Post;
class Posts extends Controller
{
public $implement = [
\Backend\Behaviors\FormController::class,
\Backend\Behaviors\ListController::class,
\Backend\Behaviors\ImportExportController::class
];
public $formConfig = 'config_form.yaml';
public $listConfig = 'config_list.yaml';
public $importExportConfig = 'config_import_export.yaml';
public $requiredPermissions = ['rainlab.blog.access_other_posts', 'rainlab.blog.access_posts'];
public function __construct()
{
parent::__construct();
BackendMenu::setContext('RainLab.Blog', 'blog', 'posts');
}
public function index()
{
$this->vars['postsTotal'] = Post::count();
$this->vars['postsPublished'] = Post::isPublished()->count();
$this->vars['postsDrafts'] = $this->vars['postsTotal'] - $this->vars['postsPublished'];
$this->asExtension('ListController')->index();
}
public function create()
{
BackendMenu::setContextSideMenu('new_post');
$this->bodyClass = 'compact-container';
$this->addCss('/plugins/rainlab/blog/assets/css/rainlab.blog-preview.css');
$this->addJs('/plugins/rainlab/blog/assets/js/post-form.js');
return $this->asExtension('FormController')->create();
}
public function update($recordId = null)
{
$this->bodyClass = 'compact-container';
$this->addCss('/plugins/rainlab/blog/assets/css/rainlab.blog-preview.css');
$this->addJs('/plugins/rainlab/blog/assets/js/post-form.js');
return $this->asExtension('FormController')->update($recordId);
}
public function export()
{
$this->addCss('/plugins/rainlab/blog/assets/css/rainlab.blog-export.css');
return $this->asExtension('ImportExportController')->export();
}
public function listExtendQuery($query)
{
if (!$this->user->hasAnyAccess(['rainlab.blog.access_other_posts'])) {
$query->where('user_id', $this->user->id);
}
}
public function formExtendQuery($query)
{
if (!$this->user->hasAnyAccess(['rainlab.blog.access_other_posts'])) {
$query->where('user_id', $this->user->id);
}
}
public function formExtendFieldsBefore($widget)
{
if (!$model = $widget->model) {
return;
}
if ($model instanceof Post && $model->isClassExtendedWith('RainLab.Translate.Behaviors.TranslatableModel')) {
$widget->secondaryTabs['fields']['content']['type'] = 'RainLab\Blog\FormWidgets\MLBlogMarkdown';
}
}
public function index_onDelete()
{
if (($checkedIds = post('checked')) && is_array($checkedIds) && count($checkedIds)) {
foreach ($checkedIds as $postId) {
if ((!$post = Post::find($postId)) || !$post->canEdit($this->user)) {
continue;
}
$post->delete();
}
Flash::success(Lang::get('rainlab.blog::lang.post.delete_success'));
}
return $this->listRefresh();
}
/**
* {@inheritDoc}
*/
public function listInjectRowClass($record, $definition = null)
{
if (!$record->published) {
return 'safe disabled';
}
}
public function formBeforeCreate($model)
{
$model->user_id = $this->user->id;
}
public function onRefreshPreview()
{
$data = post('Post');
$previewHtml = Post::formatHtml($data['content'], true);
return [
'preview' => $previewHtml
];
}
}

View File

@ -0,0 +1,23 @@
<div data-control="toolbar">
<a href="<?= Backend::url('rainlab/blog/categories/create') ?>" class="btn btn-primary oc-icon-plus">
<?= e(trans('rainlab.blog::lang.categories.new_category')) ?>
</a>
<button
class="btn btn-default oc-icon-trash-o"
disabled="disabled"
onclick="$(this).data('request-data', {
checked: $('.control-list').listWidget('getChecked')
})"
data-request="onDelete"
data-request-confirm="<?= e(trans('rainlab.blog::lang.blog.delete_confirm')) ?>"
data-trigger-action="enable"
data-trigger=".control-list input[type=checkbox]"
data-trigger-condition="checked"
data-request-success="$(this).prop('disabled', false)"
data-stripe-load-indicator>
<?= e(trans('backend::lang.list.delete_selected')) ?>
</button>
<a href="<?= Backend::url('rainlab/blog/categories/reorder') ?>" class="btn btn-default oc-icon-sitemap">
<?= e(trans('rainlab.blog::lang.category.reorder')) ?>
</a>
</div>

View File

@ -0,0 +1,5 @@
<div data-control="toolbar">
<a href="<?= Backend::url('rainlab/blog/categories') ?>" class="btn btn-primary oc-icon-caret-left">
<?= e(trans('rainlab.blog::lang.category.return_to_categories')) ?>
</a>
</div>

View File

@ -0,0 +1,16 @@
# ===================================
# Form Behavior Config
# ===================================
name: rainlab.blog::lang.blog.create_category
form: ~/plugins/rainlab/blog/models/category/fields.yaml
modelClass: RainLab\Blog\Models\Category
defaultRedirect: rainlab/blog/categories
create:
redirect: rainlab/blog/categories/update/:id
redirectClose: rainlab/blog/categories
update:
redirect: rainlab/blog/categories
redirectClose: rainlab/blog/categories

View File

@ -0,0 +1,38 @@
# ===================================
# List Behavior Config
# ===================================
# Model List Column configuration
list: ~/plugins/rainlab/blog/models/category/columns.yaml
# Model Class name
modelClass: RainLab\Blog\Models\Category
# List Title
title: rainlab.blog::lang.categories.list_title
# Link URL for each record
recordUrl: rainlab/blog/categories/update/:id
# Message to display if the list is empty
noRecordsMessage: backend::lang.list.no_records
# Records to display per page
recordsPerPage: 5
# Display checkboxes next to each record
showCheckboxes: true
showTree: true
# Toolbar widget configuration
toolbar:
# Partial for toolbar buttons
buttons: list_toolbar
# Search widget configuration
search:
prompt: backend::lang.list.search_prompt

View File

@ -0,0 +1,17 @@
# ===================================
# Reorder Behavior Config
# ===================================
# Reorder Title
title: rainlab.blog::lang.category.reorder
# Attribute name
nameFrom: name
# Model Class name
modelClass: RainLab\Blog\Models\Category
# Toolbar widget configuration
toolbar:
# Partial for toolbar buttons
buttons: reorder_toolbar

View File

@ -0,0 +1,46 @@
<?php Block::put('breadcrumb') ?>
<ul>
<li><a href="<?= Backend::url('rainlab/blog/posts') ?>"><?= e(trans('rainlab.blog::lang.blog.menu_label')) ?></a></li>
<li><?= e(trans($this->pageTitle)) ?></li>
</ul>
<?php Block::endPut() ?>
<?php if (!$this->fatalError): ?>
<?= Form::open(['class' => 'layout']) ?>
<div class="layout-row">
<?= $this->formRender() ?>
</div>
<div class="form-buttons">
<div class="loading-indicator-container">
<button
type="submit"
data-request="onSave"
data-hotkey="ctrl+s, cmd+s"
data-load-indicator="<?= e(trans('backend::lang.form.saving')) ?>"
class="btn btn-primary">
<?= e(trans('backend::lang.form.create')) ?>
</button>
<button
type="button"
data-request="onSave"
data-request-data="close:1"
data-hotkey="ctrl+enter, cmd+enter"
data-load-indicator="<?= e(trans('backend::lang.form.saving')) ?>"
class="btn btn-default">
<?= e(trans('backend::lang.form.create_and_close')) ?>
</button>
<span class="btn-text">
<?= e(trans('backend::lang.form.or')) ?> <a href="<?= Backend::url('rainlab/blog/categories') ?>"><?= e(trans('backend::lang.form.cancel')) ?></a>
</span>
</div>
</div>
<?= Form::close() ?>
<?php else: ?>
<p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
<p><a href="<?= Backend::url('rainlab/blog/posts') ?>" class="btn btn-default"><?= e(trans('rainlab.blog::lang.category.return_to_categories')) ?></a></p>
<?php endif ?>

View File

@ -0,0 +1,2 @@
<?= $this->listRender() ?>

View File

@ -0,0 +1 @@
<?= $this->reorderRender() ?>

View File

@ -0,0 +1,54 @@
<?php Block::put('breadcrumb') ?>
<ul>
<li><a href="<?= Backend::url('rainlab/blog/posts') ?>"><?= e(trans('rainlab.blog::lang.blog.menu_label')) ?></a></li>
<li><?= e(trans($this->pageTitle)) ?></li>
</ul>
<?php Block::endPut() ?>
<?php if (!$this->fatalError): ?>
<?= Form::open(['class' => 'layout']) ?>
<div class="layout-row">
<?= $this->formRender() ?>
</div>
<div class="form-buttons">
<div class="loading-indicator-container">
<button
type="submit"
data-request="onSave"
data-request-data="redirect:0"
data-hotkey="ctrl+s, cmd+s"
data-load-indicator="<?= e(trans('backend::lang.form.saving')) ?>"
class="btn btn-primary">
<?= e(trans('backend::lang.form.save')) ?>
</button>
<button
type="button"
data-request="onSave"
data-request-data="close:1"
data-hotkey="ctrl+enter, cmd+enter"
data-load-indicator="<?= e(trans('backend::lang.form.saving')) ?>"
class="btn btn-default">
<?= e(trans('backend::lang.form.save_and_close')) ?>
</button>
<button
type="button"
class="oc-icon-trash-o btn-icon danger pull-right"
data-request="onDelete"
data-load-indicator="<?= e(trans('backend::lang.form.deleting')) ?>"
data-request-confirm="<?= e(trans('rainlab.blog::lang.category.delete_confirm')) ?>">
</button>
<span class="btn-text">
<?= e(trans('backend::lang.form.or')) ?> <a href="<?= Backend::url('rainlab/blog/categories') ?>"><?= e(trans('backend::lang.form.cancel')) ?></a>
</span>
</div>
</div>
<?= Form::close() ?>
<?php else: ?>
<p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
<p><a href="<?= Backend::url('rainlab/blog/posts') ?>" class="btn btn-default"><?= e(trans('rainlab.blog::lang.category.return_to_categories')) ?></a></p>
<?php endif ?>

View File

@ -0,0 +1,37 @@
<div data-control="toolbar">
<a
href="<?= Backend::url('rainlab/blog/posts/create') ?>"
class="btn btn-primary oc-icon-plus">
<?= e(trans('rainlab.blog::lang.posts.new_post')) ?>
</a>
<button
class="btn btn-default oc-icon-trash-o"
disabled="disabled"
onclick="$(this).data('request-data', {
checked: $('.control-list').listWidget('getChecked')
})"
data-request="onDelete"
data-request-confirm="<?= e(trans('rainlab.blog::lang.blog.delete_confirm')) ?>"
data-trigger-action="enable"
data-trigger=".control-list input[type=checkbox]"
data-trigger-condition="checked"
data-request-success="$(this).prop('disabled', true)"
data-stripe-load-indicator>
<?= e(trans('backend::lang.list.delete_selected')) ?>
</button>
<?php if ($this->user->hasAnyAccess(['rainlab.blog.access_import_export'])): ?>
<!-- <div class="btn-group">
<a
href="<?= Backend::url('rainlab/blog/posts/export') ?>"
class="btn btn-default oc-icon-download">
<?= e(trans('rainlab.blog::lang.posts.export_post')) ?>
</a>
<a
href="<?= Backend::url('rainlab/blog/posts/import') ?>"
class="btn btn-default oc-icon-upload">
<?= e(trans('rainlab.blog::lang.posts.import_post')) ?>
</a>
</div> -->
<?php endif ?>
</div>

View File

@ -0,0 +1,56 @@
<?php
$isCreate = $this->formGetContext() == 'create';
$pageUrl = isset($pageUrl) ? $pageUrl : null;
?>
<div class="form-buttons loading-indicator-container">
<!-- Save -->
<a
href="javascript:;"
class="btn btn-primary oc-icon-check save"
data-request="onSave"
data-load-indicator="<?= e(trans('backend::lang.form.saving')) ?>"
data-request-before-update="$(this).trigger('unchange.oc.changeMonitor')"
<?php if (!$isCreate): ?>data-request-data="redirect:0"<?php endif ?>
data-hotkey="ctrl+s, cmd+s">
<?= e(trans('backend::lang.form.save')) ?>
</a>
<?php if (!$isCreate): ?>
<!-- Save and Close -->
<a
href="javascript:;"
class="btn btn-primary oc-icon-check save"
data-request-before-update="$(this).trigger('unchange.oc.changeMonitor')"
data-request="onSave"
data-load-indicator="<?= e(trans('backend::lang.form.saving')) ?>">
<?= e(trans('backend::lang.form.save_and_close')) ?>
</a>
<?php endif ?>
<!-- Cancel -->
<a
href="<?= Backend::url('rainlab/blog/posts') ?>"
class="btn btn-primary oc-icon-arrow-left cancel">
<?= e(trans('backend::lang.form.cancel')) ?>
</a>
<!-- Preview -->
<a
href="<?= URL::to($pageUrl) ?>"
target="_blank"
class="btn btn-primary oc-icon-crosshairs <?php if (!false): ?>hide<?php endif ?>"
data-control="preview-button">
<?= e(trans('backend::lang.form.preview_title')) ?>
</a>
<?php if (!$isCreate): ?>
<!-- Delete -->
<button
type="button"
class="btn btn-default empty oc-icon-trash-o"
data-request="onDelete"
data-request-confirm="<?= e(trans('rainlab.blog::lang.post.delete_confirm')) ?>"
data-control="delete-button"></button>
<?php endif ?>
</div>

View File

@ -0,0 +1,43 @@
# ===================================
# Filter Scope Definitions
# ===================================
scopes:
category:
# Filter name
label: rainlab.blog::lang.posts.filter_category
# Model Class name
modelClass: RainLab\Blog\Models\Category
# Model attribute to display for the name
nameFrom: name
# Apply query scope
scope: FilterCategories
published:
# Filter name
label: rainlab.blog::lang.posts.filter_published
# Filter type
type: switch
# SQL Conditions
conditions:
- published <> '1'
- published = '1'
published_date:
# Filter name
label: rainlab.blog::lang.posts.filter_date
# Filter type
type: daterange
# SQL Conditions
conditions: created_at >= ':after' AND created_at <= ':before'

View File

@ -0,0 +1,16 @@
# ===================================
# Form Behavior Config
# ===================================
name: rainlab.blog::lang.blog.create_post
form: ~/plugins/rainlab/blog/models/post/fields.yaml
modelClass: RainLab\Blog\Models\Post
defaultRedirect: rainlab/blog/posts
create:
redirect: rainlab/blog/posts/update/:id
redirectClose: rainlab/blog/posts
update:
redirect: rainlab/blog/posts
redirectClose: rainlab/blog/posts

View File

@ -0,0 +1,41 @@
# ===================================
# Import/Export Behavior Config
# ===================================
import:
# Page title
title: rainlab.blog::lang.posts.import_post
# Import List Column configuration
list: $/rainlab/blog/models/postimport/columns.yaml
# Import Form Field configuration
form: $/rainlab/blog/models/postimport/fields.yaml
# Import Model class
modelClass: RainLab\Blog\Models\PostImport
# Redirect when finished
redirect: rainlab/blog/posts
# Required permissions
permissions: rainlab.blog.access_import_export
export:
# Page title
title: rainlab.blog::lang.posts.export_post
# Output file name
fileName: posts.csv
# Export List Column configuration
list: $/rainlab/blog/models/postexport/columns.yaml
# Export Model class
modelClass: RainLab\Blog\Models\PostExport
# Redirect when finished
redirect: rainlab/blog/posts
# Required permissions
permissions: rainlab.blog.access_import_export

View File

@ -0,0 +1,47 @@
# ===================================
# List Behavior Config
# ===================================
# Model List Column configuration
list: ~/plugins/rainlab/blog/models/post/columns.yaml
# Model Class name
modelClass: RainLab\Blog\Models\Post
# List Title
title: rainlab.blog::lang.posts.list_title
# Link URL for each record
recordUrl: rainlab/blog/posts/update/:id
# Message to display if the list is empty
noRecordsMessage: backend::lang.list.no_records
# Records to display per page
recordsPerPage: 25
# Displays the list column set up button
showSetup: true
# Displays the sorting link on each column
showSorting: true
# Default sorting column
defaultSort:
column: published_at
direction: desc
# Display checkboxes next to each record
showCheckboxes: true
# Toolbar widget configuration
toolbar:
# Partial for toolbar buttons
buttons: list_toolbar
# Search widget configuration
search:
prompt: backend::lang.list.search_prompt
# Filter widget configuration
filter: config_filter.yaml

View File

@ -0,0 +1,23 @@
<?php if (!$this->fatalError): ?>
<div class="layout fancy-layout">
<?= Form::open([
'class' => 'layout',
'data-change-monitor' => 'true',
'data-window-close-confirm' => e(trans('rainlab.blog::lang.post.close_confirm')),
'id' => 'post-form'
]) ?>
<?= $this->formRender() ?>
<?= Form::close() ?>
</div>
<?php else: ?>
<div class="control-breadcrumb">
<?= Block::placeholder('breadcrumb') ?>
</div>
<div class="padded-container">
<p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
<p><a href="<?= Backend::url('rainlab/blog/posts') ?>" class="btn btn-default"><?= e(trans('rainlab.blog::lang.post.return_to_posts')) ?></a></p>
</div>
<?php endif ?>

View File

@ -0,0 +1,27 @@
<?php Block::put('breadcrumb') ?>
<ul>
<li><a href="<?= Backend::url('rainlab/blog/posts') ?>"><?= e(trans('rainlab.blog::lang.blog.menu_label')) ?></a></li>
<li><?= e(trans($this->pageTitle)) ?></li>
</ul>
<?php Block::endPut() ?>
<?= Form::open(['class' => 'layout']) ?>
<div class="layout-row">
<?= $this->exportRender() ?>
</div>
<div class="form-buttons">
<div class="loading-indicator-container">
<button
type="submit"
data-control="popup"
data-handler="onExportLoadForm"
data-keyboard="false"
class="btn btn-primary">
<?= e(trans('rainlab.blog::lang.posts.export_post')) ?>
</button>
</div>
</div>
<?= Form::close() ?>

View File

@ -0,0 +1,25 @@
<?php Block::put('breadcrumb') ?>
<ul>
<li><a href="<?= Backend::url('rainlab/blog/posts') ?>"><?= e(trans('rainlab.blog::lang.blog.menu_label')) ?></a></li>
<li><?= e(trans($this->pageTitle)) ?></li>
</ul>
<?php Block::endPut() ?>
<?= Form::open(['class' => 'layout']) ?>
<div class="layout-row">
<?= $this->importRender() ?>
</div>
<div class="form-buttons">
<button
type="submit"
data-control="popup"
data-handler="onImportLoadForm"
data-keyboard="false"
class="btn btn-primary">
<?= e(trans('rainlab.blog::lang.posts.import_post')) ?>
</button>
</div>
<?= Form::close() ?>

View File

@ -0,0 +1 @@
<?= $this->listRender() ?>

View File

@ -0,0 +1,25 @@
<?php if (!$this->fatalError): ?>
<div class="layout fancy-layout">
<?= Form::open([
'class' => 'layout',
'data-change-monitor' => 'true',
'data-window-close-confirm' => e(trans('rainlab.blog::lang.post.close_confirm')),
'id' => 'post-form'
]) ?>
<?= $this->formRender() ?>
<?= Form::close() ?>
</div>
<?php else: ?>
<div class="control-breadcrumb">
<?= Block::placeholder('breadcrumb') ?>
</div>
<div class="padded-container">
<p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
<p><a href="<?= Backend::url('rainlab/blog/posts') ?>" class="btn btn-default"><?= e(trans('rainlab.blog::lang.post.return_to_posts')) ?></a></p>
</div>
<?php endif ?>

View File

@ -0,0 +1,133 @@
<?php namespace RainLab\Blog\FormWidgets;
use Lang;
use Input;
use Response;
use Validator;
use RainLab\Blog\Models\Post as PostModel;
use Backend\Classes\FormWidgetBase;
use Backend\FormWidgets\MarkdownEditor;
use System\Models\File;
use ValidationException;
use SystemException;
use Exception;
/**
* Special markdown editor for the Create/Edit Post form.
*
* @package rainlab\blog
* @author Alexey Bobkov, Samuel Georges
*/
class BlogMarkdown extends MarkdownEditor
{
/**
* {@inheritDoc}
*/
public function init()
{
$this->viewPath = base_path().'/modules/backend/formwidgets/markdowneditor/partials';
$this->checkUploadPostback();
parent::init();
}
/**
* {@inheritDoc}
*/
protected function loadAssets()
{
$this->assetPath = '/modules/backend/formwidgets/markdowneditor/assets';
parent::loadAssets();
}
/**
* Disable HTML cleaning on the widget level since the PostModel will handle it
*
* @return boolean
*/
protected function shouldCleanHtml()
{
return false;
}
/**
* {@inheritDoc}
*/
public function onRefresh()
{
$content = post($this->formField->getName());
$previewHtml = PostModel::formatHtml($content, true);
return [
'preview' => $previewHtml
];
}
/**
* Handle images being uploaded to the blog post
*
* @return void
*/
protected function checkUploadPostback()
{
if (!post('X_BLOG_IMAGE_UPLOAD')) {
return;
}
$uploadedFileName = null;
try {
$uploadedFile = Input::file('file');
if ($uploadedFile)
$uploadedFileName = $uploadedFile->getClientOriginalName();
$validationRules = ['max:'.File::getMaxFilesize()];
$validationRules[] = 'mimes:jpg,jpeg,bmp,png,gif';
$validation = Validator::make(
['file_data' => $uploadedFile],
['file_data' => $validationRules]
);
if ($validation->fails()) {
throw new ValidationException($validation);
}
if (!$uploadedFile->isValid()) {
throw new SystemException(Lang::get('cms::lang.asset.file_not_valid'));
}
$fileRelation = $this->model->content_images();
$file = new File();
$file->data = $uploadedFile;
$file->is_public = true;
$file->save();
$fileRelation->add($file, $this->sessionKey);
$result = [
'file' => $uploadedFileName,
'path' => $file->getPath()
];
$response = Response::make()->setContent($result);
$this->controller->setResponse($response);
} catch (Exception $ex) {
$message = $uploadedFileName
? Lang::get('cms::lang.asset.error_uploading_file', ['name' => $uploadedFileName, 'error' => $ex->getMessage()])
: $ex->getMessage();
$result = [
'error' => $message,
'file' => $uploadedFileName
];
$response = Response::make()->setContent($result);
$this->controller->setResponse($response);
}
}
}

View File

@ -0,0 +1,137 @@
<?php namespace RainLab\Blog\FormWidgets;
use RainLab\Blog\Models\Post;
use RainLab\Translate\Models\Locale;
/**
* A multi-lingual version of the blog markdown editor.
* This class should never be invoked without the RainLab.Translate plugin.
*
* @package rainlab\blog
* @author Alexey Bobkov, Samuel Georges
*/
class MLBlogMarkdown extends BlogMarkdown
{
use \RainLab\Translate\Traits\MLControl;
/**
* {@inheritDoc}
*/
protected $defaultAlias = 'mlmarkdowneditor';
public $originalAssetPath;
public $originalViewPath;
/**
* @var bool legacyMode disables the Vue integration
*/
public $legacyMode = true;
/**
* {@inheritDoc}
*/
public function init()
{
parent::init();
$this->initLocale();
}
/**
* {@inheritDoc}
*/
public function render()
{
$this->actAsParent();
$parentContent = parent::render();
$this->actAsParent(false);
if (!$this->isAvailable) {
return $parentContent;
}
$this->vars['markdowneditor'] = $parentContent;
$this->actAsControl(true);
return $this->makePartial('mlmarkdowneditor');
}
public function prepareVars()
{
parent::prepareVars();
$this->prepareLocaleVars();
}
/**
* Returns an array of translated values for this field
* @param $value
* @return array
*/
public function getSaveValue($value)
{
$localeData = $this->getLocaleSaveData();
/*
* Set the translated values to the model
*/
if ($this->model->methodExists('setAttributeTranslated')) {
foreach ($localeData as $locale => $value) {
$this->model->setAttributeTranslated('content', $value, $locale);
$this->model->setAttributeTranslated(
'content_html',
Post::formatHtml($value),
$locale
);
}
}
return array_get($localeData, $this->defaultLocale->code, $value);
}
/**
* {@inheritDoc}
*/
protected function loadAssets()
{
$this->actAsParent();
parent::loadAssets();
$this->actAsParent(false);
if (Locale::isAvailable()) {
$this->loadLocaleAssets();
$this->actAsControl(true);
$this->addJs('js/mlmarkdowneditor.js');
$this->actAsControl(false);
}
}
protected function actAsParent($switch = true)
{
if ($switch) {
$this->originalAssetPath = $this->assetPath;
$this->originalViewPath = $this->viewPath;
$this->assetPath = '/modules/backend/formwidgets/markdowneditor/assets';
$this->viewPath = base_path('/modules/backend/formwidgets/markdowneditor/partials');
}
else {
$this->assetPath = $this->originalAssetPath;
$this->viewPath = $this->originalViewPath;
}
}
protected function actAsControl($switch = true)
{
if ($switch) {
$this->originalAssetPath = $this->assetPath;
$this->originalViewPath = $this->viewPath;
$this->assetPath = '/plugins/rainlab/translate/formwidgets/mlmarkdowneditor/assets';
$this->viewPath = base_path('/plugins/rainlab/translate/formwidgets/mlmarkdowneditor/partials');
}
else {
$this->assetPath = $this->originalAssetPath;
$this->viewPath = $this->originalViewPath;
}
}
}

View File

@ -0,0 +1,100 @@
<?php
return [
'plugin' => [
'name' => 'Блог',
'description' => 'Стабилната блог платформа.'
],
'blog' => [
'menu_label' => 'Блог',
'menu_description' => 'управление на публикациите',
'posts' => 'публикации',
'create_post' => 'създай публикация',
'categories' => 'категории',
'create_category' => 'създай категория',
'tab' => 'Блог',
'access_posts' => 'управление на публикациите',
'access_categories' => 'управление на категории',
'access_other_posts' => 'управление на други потребители публикации в блога',
'delete_confirm' => 'Сигурни ли сте?',
'chart_published' => 'Публикувано',
'chart_drafts' => 'Чернови',
'chart_total' => 'Общо'
],
'posts' => [
'list_title' => 'Управление публикациите в блога',
'filter_category' => 'Категория',
'filter_published' => 'Скрий публикуваните',
'new_post' => 'Нова публикация'
],
'post' => [
'title' => 'Заглавие',
'title_placeholder' => 'Ново заглавие на публикацията',
'slug' => 'Slug',
'slug_placeholder' => 'нов slug на публикацията',
'categories' => 'Категории',
'created' => 'Създаден',
'updated' => 'Обновен',
'published' => 'Публикуван',
'published_validation' => 'Моля, посочете дата на публикуване',
'tab_edit' => 'Промяна',
'tab_categories' => 'Категории',
'categories_comment' => 'Изберете категории към който пренадлежи публикацията ',
'categories_placeholder' => 'Няма категирии, Създайте първата?!',
'tab_manage' => 'Управление',
'published_on' => 'публикувано в',
'excerpt' => 'Откъс',
'featured_images' => 'Избрани снимки',
'delete_confirm' => 'Наистина ли искате да изтриете тази публикация?',
'close_confirm' => 'Публикацията не е запазена.',
'return_to_posts' => 'Върни ме към всички публикации'
],
'categories' => [
'list_title' => 'Управление категориите в блога',
'new_category' => 'Нова категория',
'uncategorized' => 'Без категория'
],
'category' => [
'name' => 'Име',
'name_placeholder' => 'Ново име на категорията',
'slug' => 'Slug',
'slug_placeholder' => 'нов slug на категотията',
'posts' => 'публикации',
'delete_confirm' => 'Наистина ли искате да изтриете тази категория?',
'return_to_categories' => 'Върни ме към всички категории'
],
'settings' => [
'category_title' => 'Списък с категории',
'category_description' => 'Показва списък с категориите на блога.',
'category_slug' => 'категория slug',
'category_slug_description' => "Look up the blog category using the supplied slug value. This property is used by the default component partial for marking the currently active category.",
'category_display_empty' => 'Показване на празни категории',
'category_display_empty_description' => 'Показване на категории, които нямат никакви публикации.',
'category_page' => 'Страница на категория',
'category_page_description' => 'Име на страницата за категирия. Това се използва подразбиране от компонента.',
'post_title' => 'Публикация',
'post_description' => 'Показване на Публикациите в блога на страницата.',
'post_slug' => 'Post slug',
'post_slug_description' => "Търсене на публикации по зададен slug.",
'post_category' => 'Страница за Категория',
'post_category_description' => 'Име на страница за категория за генериране на линк.Това се използва подразбиране от компонента.',
'posts_title' => 'Лист с Публикации',
'posts_description' => 'Показване на лист с публикации на страницата.',
'posts_pagination' => 'Номер на страницата',
'posts_pagination_description' => 'Тази стойност се използва за определяне на коя страница е потребителя.',
'posts_filter' => 'Филтер Категория',
'posts_filter_description' => 'Въведи slug на категория или URL адрес за филтриране по. Оставете празно за да се покажат всички публикации.',
'posts_per_page' => 'Публикации на страница',
'posts_per_page_validation' => 'Невалиден формат за публикации на страница',
'posts_no_posts' => 'Няма публикации',
'posts_no_posts_description' => 'Съобщение което да се покаже, в случай ,че няма публикации за показване.Това се използва подразбиране от компонента.',
'posts_order' => 'подреждане на публикации',
'posts_order_description' => 'Атрибут по който да бъдат подредени публикациите',
'posts_category' => 'страница на категориите',
'posts_category_description' => 'Име на страницата за категории , за "публикувано в". Това се използва подразбиране от компонента.',
'posts_post' => 'Post page',
'posts_post_description' => 'Име на страницата за публикации "Прочетете повече". Това се използва подразбиране от компонента.',
'posts_except_post' => 'Except post',
'posts_except_post_description' => 'Enter ID/URL or variable with post ID/URL you want to except',
]
];

View File

@ -0,0 +1,154 @@
<?php
return [
'plugin' => [
'name' => 'Blog',
'description' => 'Robustní blogová platforma.'
],
'blog' => [
'menu_label' => 'Blog',
'menu_description' => 'Správa blogových příspěvků',
'posts' => 'Příspěvky',
'create_post' => 'Příspěvek',
'categories' => 'Kategorie',
'create_category' => 'Kategorie příspěvků',
'tab' => 'Blog',
'access_posts' => 'Správa blogových příspěvků',
'access_categories' => 'Správa blogových kategorií',
'access_other_posts' => 'Správa příspěvků ostatních uživatelů',
'access_import_export' => 'Možnost importu a exportu příspěvků',
'access_publish' => 'Možnost publikovat příspěvky',
'delete_confirm' => 'Jste si jistí?',
'chart_published' => 'Publikované',
'chart_drafts' => 'Návrhy',
'chart_total' => 'Celkem',
],
'posts' => [
'list_title' => 'Správa blogových příspěvků',
'filter_category' => 'Kategorie',
'filter_published' => 'Schovat publikované',
'filter_date' => 'Datum',
'new_post' => 'Nový příspěvek',
'export_post' => 'Export příspěvků',
'import_post' => 'Import příspěvků',
],
'post' => [
'title' => 'Název',
'title_placeholder' => 'Zadejte název',
'content' => 'Obsah',
'content_html' => 'HTML obsah',
'slug' => 'URL příspěvku',
'slug_placeholder' => 'zadejte-url-prispevku',
'categories' => 'Kategorie',
'author_email' => 'E-mail autora',
'created' => 'Vytvořeno',
'created_date' => 'Vytvořeno dne',
'updated' => 'Upraveno',
'updated_date' => 'Upraveno dne',
'published' => 'Publikováno',
'published_date' => 'Publikováno dne',
'published_validation' => 'Zadejte prosím datum publikace příspěvku',
'tab_edit' => 'Upravit',
'tab_categories' => 'Kategorie',
'categories_comment' => 'Vyberte kategorie do kterých příspěvek patří',
'categories_placeholder' => 'Nejsou zde žádné kategorie, nejdříve musíte nějaké vytvořit!',
'tab_manage' => 'Nastavení',
'published_on' => 'Publikováno dne',
'excerpt' => 'Perex příspěvku',
'summary' => 'Shrnutí',
'featured_images' => 'Obrázky',
'delete_confirm' => 'Opravdu chcete smazat tento příspěvek?',
'delete_success' => 'Vybrané příspěvky úspěšně odstraněny.',
'close_confirm' => 'Příspěvek není uložený.',
'return_to_posts' => 'Zpět na seznam příspěvků',
],
'categories' => [
'list_title' => 'Správa blogových kategorií',
'new_category' => 'Nová kategorie',
'uncategorized' => 'Nezařazeno',
],
'category' => [
'name' => 'Název',
'name_placeholder' => 'Název nové kategorie',
'description' => 'Popis',
'slug' => 'URL kategorie',
'slug_placeholder' => 'zadejte-url-kategorie',
'posts' => 'Počet příspěvků',
'delete_confirm' => 'Opravdu chcete smazat tuto kategorii?',
'delete_success' => 'Vybrané kategorie úspěšně odstraněny.',
'return_to_categories' => 'Zpět na seznam blogových kategorií',
'reorder' => 'Změnit pořadí',
],
'menuitem' => [
'blog_category' => 'Blogová kategorie',
'all_blog_categories' => 'Všechny blogové kategorie',
'blog_post' => 'Blogový příspěvek',
'all_blog_posts' => 'Všechny blogové příspěvky',
'category_blog_posts' => 'Blog category posts'
],
'settings' => [
'category_title' => 'Seznam kategorií',
'category_description' => 'Zobrazí na stránce seznam blogových kategorií.',
'category_slug' => 'URL kategorie',
'category_slug_description' => "Najde blogovou kategorii s tímto URL. Používá se pro zobrazení aktivní kategorie.",
'category_display_empty' => 'Zobrazit prázdné kategorie',
'category_display_empty_description' => 'Zobrazit kategorie bez blogových příspěvků.',
'category_page' => 'Stránka kategorií',
'category_page_description' => 'Vyberte stránku která slouží k zobrazení všech kategorií (nebo detailu kategorie).',
'post_title' => 'Příspěvek',
'post_description' => 'Zobrazí blogový příspěvek na stránce.',
'post_slug' => 'URL příspěvku',
'post_slug_description' => "Najde příspěvek dle zadané URL.",
'post_category' => 'Stránka kategorie',
'post_category_description' => 'Vyberte stránku která slouží k zobrazení všech kategorií (nebo detailu kategorie).',
'posts_title' => 'Seznam příspěvků',
'posts_description' => 'Zobrazí na stránce seznam posledních příspěvků na stránkách.',
'posts_pagination' => 'Číslo stránky',
'posts_pagination_description' => 'Číslo stránky určující na které stránce se uživatel nachází. Použito pro stránkování.',
'posts_filter' => 'Filtr kategorií',
'posts_filter_description' => 'Zadejte URL kategorie, nebo URL parametr pro filtrování příspěvků. Nechte prázdné pro zobrazení všech příspěvků.',
'posts_per_page' => 'Příspěvků na stránku',
'posts_per_page_validation' => 'Špatný formát počtu příspěvků na stránku, musí být zadáno jako číslo',
'posts_no_posts' => 'Hláška prázdné stránky',
'posts_no_posts_description' => 'Zpráva se zobrazí pokud se nepovede najít žádné články.',
'posts_no_posts_default' => 'Nenalezeny žádné příspěvky',
'posts_order' => 'Řazení článků',
'posts_order_decription' => 'Nastaví řazení článků ve výpisu',
'posts_category' => 'Stránka kategorií',
'posts_category_description' => 'Vyberte stránku která slouží k zobrazení všech kategorií (nebo detailu kategorie).',
'posts_post' => 'Stránka příspěvků',
'posts_post_description' => 'Vyberte stránku která slouží k zobrazení článků (nebo detailu článku).',
'posts_except_post' => 'Vyloučit příspěvěk',
'posts_except_post_description' => 'Zadejte ID nebo URL příspěvku který chcete vyloučit',
'posts_except_categories' => 'Vyloučené kategorie',
'posts_except_categories_description' => 'Pro vyloučení kategorií zadejte čárkou oddělené URL příspěvků nebo proměnnou, která tento seznam obsahuje.',
'rssfeed_blog' => 'Blogová stránka',
'rssfeed_blog_description' => 'Name of the main blog page file for generating links. This property is used by the default component partial.',
'rssfeed_title' => 'RSS Kanál',
'rssfeed_description' => 'Vygeneruje RSS kanál který obsahuje blogové příspěvky.',
'group_links' => 'Odkazy',
'group_exceptions' => 'Výjimky'
],
'sorting' => [
'title_asc' => 'Název (sestupně)',
'title_desc' => 'Název (vzestupně)',
'created_asc' => 'Vytvořeno (sestupně)',
'created_desc' => 'Vytvořeno (vzestupně)',
'updated_asc' => 'Upraveno (sestupně)',
'updated_desc' => 'Upraveno (vzestupně)',
'published_asc' => 'Publikováno (sestupně)',
'published_desc' => 'Publikováno (vzestupně)',
'random' => 'Náhodně'
],
'import' => [
'update_existing_label' => 'Uprav existující příspěvky',
'update_existing_comment' => 'Zvolte pokud chcete upravit příspěvky se stejným ID, názvem nebo URL.',
'auto_create_categories_label' => 'VYtvořit kategorie ze souboru',
'auto_create_categories_comment' => 'Chcete-li tuto funkci použít, měli byste se shodovat se sloupcem Kategorie, jinak vyberte výchozí kategorie, které chcete použít z níže uvedených položek.',
'categories_label' => 'Kategorie',
'categories_comment' => 'Vyberte kategorie ke kterým budou příspěvky přiřazeny (volitelné).',
'default_author_label' => 'Výchozí autor příspěvků (volitelné)',
'default_author_comment' => 'Import se pokusí použít existujícího autora, pokud odpovídá sloupci email, jinak se použije výše uvedený autor.',
'default_author_placeholder' => '-- vyberte autora --'
]
];

View File

@ -0,0 +1,132 @@
<?php
return [
'plugin' => [
'name' => 'Blog',
'description' => 'Eine robuste Blog Plattform.'
],
'blog' => [
'menu_label' => 'Blog',
'menu_description' => 'Blog Artikel bearbeiten',
'posts' => 'Artikel',
'create_post' => 'Blog Artikel',
'categories' => 'Kategorien',
'create_category' => 'Blog Kategorie',
'tab' => 'Blog',
'access_posts' => 'Blog Artikel verwalten',
'access_categories' => 'Blog Kategorien verwalten',
'access_other_posts' => 'Blog Artikel anderer Benutzer verwalten',
'access_import_export' => 'Blog Artikel importieren oder exportieren',
'access_publish' => 'Kann Artikel veröffentlichen',
'delete_confirm' => 'Bist du sicher?',
'chart_published' => 'Veröffentlicht',
'chart_drafts' => 'Entwurf',
'chart_total' => 'Gesamt'
],
'posts' => [
'list_title' => 'Blog Artikel verwalten',
'filter_category' => 'Kategorie',
'filter_published' => 'Veröffentlichte ausblenden',
'filter_date' => 'Date',
'new_post' => 'Neuer Artikel',
'export_post' => 'Exportiere Artikel',
'import_post' => 'Importiere Artikel'
],
'post' => [
'title' => 'Titel',
'title_placeholder' => 'Neuer Titel',
'content' => 'Inhalt',
'content_html' => 'HTML-Inhalt',
'slug' => 'Slug',
'slug_placeholder' => 'neuer-artikel-slug',
'categories' => 'Kategorien',
'author_email' => 'Autor E-Mail',
'created' => 'Erstellt',
'created_date' => 'Erstellzeitpunkt',
'updated' => 'Aktualisiert',
'updated_date' => 'Aktualisierungszeitpunk',
'published' => 'Veröffentlicht',
'published_date' => 'Veröffentlichungszeitpunkt',
'published_validation' => 'Bitte gebe das Datum der Veröffentlichung an',
'tab_edit' => 'Bearbeiten',
'tab_categories' => 'Kategorien',
'categories_comment' => 'Wähle die zugehörigen Kategorien',
'categories_placeholder' => 'Es existieren keine Kategorien. Bitte lege zuerst Kategorien an!',
'tab_manage' => 'Verwalten',
'published_on' => 'Veröffentlicht am',
'excerpt' => 'Textauszug',
'summary' => 'Zusammenfassung',
'featured_images' => 'Zugehörige Bilder',
'delete_confirm' => 'Möchtest du diesen Artikel wirklich löschen?',
'close_confirm' => 'Der Artikel ist noch nicht gespeichert.',
'return_to_posts' => 'Zurück zur Artikel-Übersicht',
'posted_byline' => 'Veröffentlicht in :categories am :date',
'posted_byline_no_categories' => 'Veröffentlicht am :date',
'date_format' => 'd. F Y',
],
'categories' => [
'list_title' => 'Blog Kategorien verwalten',
'new_category' => 'Neue Kategorie',
'uncategorized' => 'Allgemein'
],
'category' => [
'name' => 'Name',
'name_placeholder' => 'Neuer Kategorie Name',
'description' => 'Beschreibung',
'slug' => 'Slug',
'slug_placeholder' => 'neuer-kategorie-slug',
'posts' => 'Artikel',
'delete_confirm' => 'Möchtest du die Kategorie wirklich löschen?',
'return_to_categories' => 'Zurück zur Kategorie-Übersicht.',
'reorder' => 'Kategorien sortieren'
],
'menuitem' => [
'blog_category' => 'Blog Kategorie',
'all_blog_categories' => 'Alle Blog Kategorien',
'blog_post' => 'Blog Artikel',
'all_blog_posts' => 'Alle Blog Artikel',
'category_blog_posts' => 'Blog Kategorie Artikel'
],
'settings' => [
'category_title' => 'Blog Kategorie-Übersicht',
'category_description' => 'Zeigt eine Blog Kategorien-Übersicht.',
'category_slug' => 'Slug Parametername',
'category_slug_description' => 'Der URL-Routen-Parameter welcher verwendet wird um die aktuelle Kategorie zu bestimmen. Wird von der Standard-Komponente benötigt um die aktive Kategorie zu markieren.',
'category_display_empty' => 'Leere Kategorien anzeigen',
'category_display_empty_description' => 'Kategorien zeigen welche keine Artikel besitzen.',
'category_page' => 'Kategorien Seite',
'category_page_description' => 'Name der Kategorien-Seiten-Datei für die Kategorien Links. Wird von der Standard-Komponente benötigt.',
'post_title' => 'Blog Artikel',
'post_description' => 'Zeigt einen Blog Artikel auf der Seite.',
'post_slug' => 'Slug Parametername',
'post_slug_description' => 'Der URL-Routen-Parameter um den Post mittels "Slug" zu bestimmen.',
'post_category' => 'Kategorien-Seite',
'post_category_description' => 'Name der Kategorien-Seiten-Datei für Kategorie-Links.',
'posts_title' => 'Blog Artikel-Übersicht',
'posts_description' => 'Stellt eine Liste der neuesten Artikel auf der Seite dar.',
'posts_pagination' => 'Blättern Parametername',
'posts_pagination_description' => 'Der erwartete Parametername welcher für Seiten verwendet wird.',
'posts_filter' => 'Kategorien-Filter',
'posts_filter_description' => 'Bitte gebe ein Kategorien-Slug oder URL-Parameter an, mittels den die Artikel gefiltert werden. Wenn der Wert leer ist, werden alle Artikel angezeigt.',
'posts_per_page' => 'Artikel pro Seite',
'posts_per_page_validation' => 'Ungültiger "Artikel pro Seiten" Wert',
'posts_no_posts' => 'Keine Artikel Nachricht',
'posts_no_posts_description' => 'Nachricht welche dargestellt wird wenn keine Artikel vorhanden sind. Dieser Wert wird von der Standard-Komponente verwendet.',
'posts_order' => 'Artikel Sortierung',
'posts_order_description' => 'Attribute nach welchem Artikel sortiert werden.',
'posts_category' => 'Kategorien-Seite',
'posts_category_description' => 'Name der Kategorien-Seiten-Datei für "Veröffentlicht in" Kategorien-Links. Dieser Wert von der Standard-Komponente verwendet.',
'posts_post' => 'Artikel Seite',
'posts_post_description' => 'Name der Artikel-Seiten-Datei für die "Erfahre mehr" Links. Dieser Wert für von der Standard-Komponente verwendet.',
'posts_except_post' => 'Artikel ausschließen',
'posts_except_post_description' => 'Gebe direkt die ID/URL oder eine Variable mit der Artikel-ID/URL an um diesen Artikel auszuschließen. Dieser Wert für von der Standard-Komponente verwendet.',
'posts_except_categories' => 'Kategorien ausschließen',
'posts_except_categories_description' => 'Gebe eine kommagetrennte Liste von Kategorie-Slugs oder eine Variable mit einer solchen Liste an um deren Artikel auszuschließen. Die Dieser Wert für von der Standard-Komponente verwendet.',
'rssfeed_blog' => 'Blog Seite',
'rssfeed_blog_description' => 'Name der Artikel-Seiten-Datei für die Links. Dieser Wert für von der Standard-Komponente verwendet.',
'rssfeed_title' => 'RSS-Feed',
'rssfeed_description' => 'Erstellt einen RSS-Feed mit Artikeln aus dem Blog.',
'group_links' => 'Links',
'group_exceptions' => 'Ausnahmen'
]
];

View File

@ -0,0 +1,166 @@
<?php
return [
'plugin' => [
'name' => 'Blog',
'description' => 'A robust blogging platform.'
],
'blog' => [
'menu_label' => 'Blog',
'menu_description' => 'Manage Blog Posts',
'posts' => 'Posts',
'create_post' => 'Blog post',
'categories' => 'Categories',
'create_category' => 'Blog category',
'tab' => 'Blog',
'access_posts' => 'Manage the blog posts',
'access_categories' => 'Manage the blog categories',
'access_other_posts' => 'Manage other users blog posts',
'access_import_export' => 'Allowed to import and export posts',
'access_publish' => 'Allowed to publish posts',
'manage_settings' => 'Manage blog settings',
'delete_confirm' => 'Are you sure?',
'chart_published' => 'Published',
'chart_drafts' => 'Drafts',
'chart_total' => 'Total',
'settings_description' => 'Manage blog settings',
'show_all_posts_label' => 'Show all posts to backend users',
'show_all_posts_comment' => 'Display both published and unpublished posts on the frontend to backend users',
'tab_general' => 'General'
],
'posts' => [
'list_title' => 'Manage the blog posts',
'filter_category' => 'Category',
'filter_published' => 'Published',
'filter_date' => 'Date',
'new_post' => 'New post',
'export_post' => 'Export posts',
'import_post' => 'Import posts'
],
'post' => [
'title' => 'Title',
'title_placeholder' => 'New post title',
'content' => 'Content',
'content_html' => 'HTML Content',
'slug' => 'Slug',
'slug_placeholder' => 'new-post-slug',
'categories' => 'Categories',
'author_email' => 'Author Email',
'created' => 'Created',
'created_date' => 'Created date',
'updated' => 'Updated',
'updated_date' => 'Updated date',
'published' => 'Published',
'published_by' => 'Published by',
'current_user' => 'Current user',
'published_date' => 'Published date',
'published_validation' => 'Please specify the published date',
'tab_edit' => 'Edit',
'tab_categories' => 'Categories',
'categories_comment' => 'Select categories the blog post belongs to',
'categories_placeholder' => 'There are no categories, you should create one first!',
'tab_manage' => 'Manage',
'published_on' => 'Published on',
'excerpt' => 'Excerpt',
'summary' => 'Summary',
'featured_images' => 'Featured Images',
'delete_confirm' => 'Delete this post?',
'delete_success' => 'Successfully deleted those posts.',
'close_confirm' => 'The post is not saved.',
'return_to_posts' => 'Return to posts list',
'posted_byline' => 'Posted in :categories on :date.',
'posted_byline_no_categories' => 'Posted on :date.',
'date_format' => 'M d, Y',
],
'categories' => [
'list_title' => 'Manage the blog categories',
'new_category' => 'New category',
'uncategorized' => 'Uncategorized'
],
'category' => [
'name' => 'Name',
'name_placeholder' => 'New category name',
'description' => 'Description',
'slug' => 'Slug',
'slug_placeholder' => 'new-category-slug',
'posts' => 'Posts',
'delete_confirm' => 'Delete this category?',
'delete_success' => 'Successfully deleted those categories.',
'return_to_categories' => 'Return to the blog category list',
'reorder' => 'Reorder Categories'
],
'menuitem' => [
'blog_category' => 'Blog category',
'all_blog_categories' => 'All blog categories',
'blog_post' => 'Blog post',
'all_blog_posts' => 'All blog posts',
'category_blog_posts' => 'Blog category posts'
],
'settings' => [
'category_title' => 'Category List',
'category_description' => 'Displays a list of blog categories on the page.',
'category_slug' => 'Category slug',
'category_slug_description' => "Look up the blog category using the supplied slug value. This property is used by the default component partial for marking the currently active category.",
'category_display_empty' => 'Display empty categories',
'category_display_empty_description' => 'Show categories that do not have any posts.',
'category_page' => 'Category page',
'category_page_description' => 'Name of the category page file for the category links. This property is used by the default component partial.',
'post_title' => 'Post',
'post_description' => 'Displays a blog post on the page.',
'post_slug' => 'Post slug',
'post_slug_description' => "Look up the blog post using the supplied slug value.",
'post_category' => 'Category page',
'post_category_description' => 'Name of the category page file for the category links. This property is used by the default component partial.',
'posts_title' => 'Post List',
'posts_description' => 'Displays a list of latest blog posts on the page.',
'posts_pagination' => 'Page number',
'posts_pagination_description' => 'This value is used to determine what page the user is on.',
'posts_filter' => 'Category filter',
'posts_filter_description' => 'Enter a category slug or URL parameter to filter the posts by. Leave empty to show all posts.',
'posts_per_page' => 'Posts per page',
'posts_per_page_validation' => 'Invalid format of the posts per page value',
'posts_no_posts' => 'No posts message',
'posts_no_posts_description' => 'Message to display in the blog post list in case if there are no posts. This property is used by the default component partial.',
'posts_no_posts_default' => 'No posts found',
'posts_order' => 'Post order',
'posts_order_description' => 'Attribute on which the posts should be ordered',
'posts_category' => 'Category page',
'posts_category_description' => 'Name of the category page file for the "Posted into" category links. This property is used by the default component partial.',
'posts_post' => 'Post page',
'posts_post_description' => 'Name of the blog post page file for the "Learn more" links. This property is used by the default component partial.',
'posts_except_post' => 'Except post',
'posts_except_post_description' => 'Enter ID/URL or variable with post ID/URL you want to exclude. You may use a comma-separated list to specify multiple posts.',
'posts_except_post_validation' => 'Post exceptions must be a single slug or ID, or a comma-separated list of slugs and IDs',
'posts_except_categories' => 'Except categories',
'posts_except_categories_description' => 'Enter a comma-separated list of category slugs or variable with such a list of categories you want to exclude',
'posts_except_categories_validation' => 'Category exceptions must be a single category slug, or a comma-separated list of slugs',
'rssfeed_blog' => 'Blog page',
'rssfeed_blog_description' => 'Name of the main blog page file for generating links. This property is used by the default component partial.',
'rssfeed_title' => 'RSS Feed',
'rssfeed_description' => 'Generates an RSS feed containing posts from the blog.',
'group_links' => 'Links',
'group_exceptions' => 'Exceptions'
],
'sorting' => [
'title_asc' => 'Title (ascending)',
'title_desc' => 'Title (descending)',
'created_asc' => 'Created (ascending)',
'created_desc' => 'Created (descending)',
'updated_asc' => 'Updated (ascending)',
'updated_desc' => 'Updated (descending)',
'published_asc' => 'Published (ascending)',
'published_desc' => 'Published (descending)',
'random' => 'Random'
],
'import' => [
'update_existing_label' => 'Update existing posts',
'update_existing_comment' => 'Check this box to update posts that have exactly the same ID, title or slug.',
'auto_create_categories_label' => 'Create categories specified in the import file',
'auto_create_categories_comment' => 'You should match the Categories column to use this feature, otherwise select the default categories to use from the items below.',
'categories_label' => 'Categories',
'categories_comment' => 'Select the categories that imported posts will belong to (optional).',
'default_author_label' => 'Default post author (optional)',
'default_author_comment' => 'The import will try to use an existing author if you match the Author Email column, otherwise the author specified above is used.',
'default_author_placeholder' => '-- select author --'
]
];

View File

@ -0,0 +1,166 @@
<?php
return [
'plugin' => [
'name' => 'Blog',
'description' => 'Una plataforma robusta de blogging.'
],
'blog' => [
'menu_label' => 'Blog',
'menu_description' => 'Administrar Publicaciones',
'posts' => 'Publicaciones',
'create_post' => 'Crear publicación',
'categories' => 'Categorías',
'create_category' => 'Categoría',
'tab' => 'Blog',
'access_posts' => 'Administrar las publicaciones',
'access_categories' => 'Administrar las categorías',
'access_other_posts' => 'Administrar publicaciones de otros usuarios',
'access_import_export' => 'Autorizado para importar y exportar publicaciones',
'access_publish' => 'Autorizado para publicar publicaciones',
'manage_settings' => 'Administrar configuración del blog',
'delete_confirm' => '¿Está seguro?',
'chart_published' => 'Publicado',
'chart_drafts' => 'Borradores',
'chart_total' => 'Total',
'settings_description' => 'Administrar configuración del blog',
'show_all_posts_label' => 'Mostrar todas las publicaciones a los usuarios de backend',
'show_all_posts_comment' => 'Mostrar las publicaciones publicados y los borradores a los usuarios de backend',
'tab_general' => 'General'
],
'posts' => [
'list_title' => 'Administrar publicaciones',
'filter_category' => 'Categoría',
'filter_published' => 'Publicado',
'filter_date' => 'Fecha',
'new_post' => 'Nueva publicación',
'export_post' => 'Exportar publicaciones',
'import_post' => 'Importar publicaciones'
],
'post' => [
'title' => 'Título',
'title_placeholder' => 'Título de la publicación',
'content' => 'Contenido',
'content_html' => 'Contenido HTML',
'slug' => 'Identificador',
'slug_placeholder' => 'nueva-publicacion',
'categories' => 'Categorías',
'author_email' => 'Email del Autor',
'created' => 'Creado',
'created_date' => 'Fecha de Creación',
'updated' => 'Actualizado',
'updated_date' => 'Fecha de Actualización',
'published' => 'Publicado',
'published_by' => 'Publicado por',
'current_user' => 'Usuario actual',
'published_date' => 'Fecha de publicación',
'published_validation' => 'Por favor, especifique la fecha de publicación',
'tab_edit' => 'Editar',
'tab_categories' => 'Categorías',
'categories_comment' => 'Seleccione las categorías para la publicación',
'categories_placeholder' => 'No hay categorías, ¡crea una primero!',
'tab_manage' => 'Administrar',
'published_on' => 'Publicado el',
'excerpt' => 'Resumen',
'summary' => 'Resumen',
'featured_images' => 'Imágenes Destacadas',
'delete_confirm' => '¿Borrar la publicación?',
'delete_success' => 'Publicación borrada correctamente',
'close_confirm' => 'La publicación no está guardada.',
'return_to_posts' => 'Volver a la lista de publicaciones',
'posted_byline' => 'Publicado en :categories el :date.',
'posted_byline_no_categories' => 'Publicado el :date.',
'date_format' => 'd de M de Y',
],
'categories' => [
'list_title' => 'Administrar las categorías',
'new_category' => 'Nueva categoría',
'uncategorized' => 'Sin Categoría'
],
'category' => [
'name' => 'Nombre',
'name_placeholder' => 'Nombre de la categoría',
'description' => 'Descripción',
'slug' => 'Identificador',
'slug_placeholder' => 'nueva-categoría',
'posts' => 'Publicaciones',
'delete_confirm' => '¿Borrar esta categoría?',
'delete_success' => 'Categorías borradas correctamente.',
'return_to_categories' => 'Volver a la lista de categorías',
'reorder' => 'Re-ordenar Categorías'
],
'menuitem' => [
'blog_category' => 'Categoría del blog',
'all_blog_categories' => 'Todas las categorías del blog',
'blog_post' => 'Publicación del blog',
'all_blog_posts' => 'Todas las publicaciones del blog',
'category_blog_posts' => 'Publicaciones del blog por categorías'
],
'settings' => [
'category_title' => 'Lista de Categorías',
'category_description' => 'Muestra en la página una lista de las categorías.',
'category_slug' => 'Identificador de la categoría',
'category_slug_description' => "Localiza una categoría utilizando el identificador proporcionado. Esta propiedad es utilizada dentro del parcial que viene por defecto en el componente para marcar la categoría activa.",
'category_display_empty' => 'Mostrar categorías vacías',
'category_display_empty_description' => 'Mostrar categorías que no tienen ninguna publicación.',
'category_page' => 'Página de categorías',
'category_page_description' => 'Nombre del archivo de página utilizado para los enlaces de categorías. Esta propiedad es utilizada dentro del parcial que viene por defecto en el componente.',
'post_title' => 'Publicación',
'post_description' => 'Muestra una publicación en la página.',
'post_slug' => 'Identificador de la publicación',
'post_slug_description' => "Se buscará la publicación utilizando el valor del identificador proporcionado.",
'post_category' => 'Página de categoría',
'post_category_description' => 'Nombre del archivo de página utilizado para los enlaces de categorías. Esta propiedad es utilizada dentro del parcial que viene por defecto en el componente.',
'posts_title' => 'Lista de publicaciones',
'posts_description' => 'Muestra una lista de las últimas publicaciones en la página.',
'posts_pagination' => 'Número de página',
'posts_pagination_description' => 'Este valor se utiliza para determinar en que página se encuentra el usuario.',
'posts_filter' => 'Filtro de categoría',
'posts_filter_description' => 'Ingrese un identificador de categoría o parámetro URL. Se utilizará para filtrar las publicaciones. Deje el campo vacío para mostrar todas las publicaciones.',
'posts_per_page' => 'Publicaciones por página',
'posts_per_page_validation' => 'Formato inválido para el valor de publicaciones por página',
'posts_no_posts' => 'Mensaje cuando no hay publicaciones',
'posts_no_posts_description' => 'Mensaje que se mostrará en la lista de publicaciones del blog cuando no haya ningúno. Esta propiedad es utilizada dentro del parcial que viene por defecto en el componente.',
'posts_no_posts_default' => 'No se encontraron publicaciones.',
'posts_order' => 'Ordenar publicaciones por',
'posts_order_description' => 'Atributo mediante el cual se deberán ordenar las publicaciones',
'posts_category' => 'Página de Categoría',
'posts_category_description' => 'Nombre del archivo de página utilizado para los enlaces de categoría "Publicado en". Esta propiedad es utilizada dentro del parcial que viene por defecto en el componente.',
'posts_post' => 'Página de las publicaciones',
'posts_post_description' => 'Nombre del archivo de página utilizado para los enlaces "Saber más". Esta propiedad es utilizada dentro del parcial que viene por defecto en el componente.',
'posts_except_post' => 'Exceptuar publicación',
'posts_except_post_description' => 'Ingrese una ID/URL o variable que contenga una ID/URL de la publicación que se quiera excluir',
'posts_except_post_validation' => 'La publicación a excluir debe ser una ID/URL, o una lista separada por comas de IDs/URLs',
'posts_except_categories' => 'Excluir categorías',
'posts_except_categories_description' => 'Introduce una lista separada por comas de IDs/URLs de categorías con las categorías a excluir.',
'posts_except_categories_validation' => 'Las categorías excluidas deben ser una URL de categoría o una lista separada por comas',
'rssfeed_blog' => 'Página del blog',
'rssfeed_blog_description' => 'Nombre del archivo de página principal para generación de enlaces. Esta propiedad es utilizada dentro del parcial que viene por defecto en el componente.',
'rssfeed_title' => 'RSS Feed',
'rssfeed_description' => 'Genera un feed de RSS con las publicaciones del blog.',
'group_links' => 'Enlaces',
'group_exceptions' => 'Excepciones'
],
'sorting' => [
'title_asc' => 'Título (ascendiente)',
'title_desc' => 'Título (descendiente)',
'created_asc' => 'Creado (ascendiente)',
'created_desc' => 'Creado (descendiente)',
'updated_asc' => 'Editado (ascendiente)',
'updated_desc' => 'Editado (descendiente)',
'published_asc' => 'Publicado (ascendiente)',
'published_desc' => 'Publicado (descendiente)',
'random' => 'Aleatorio'
],
'import' => [
'update_existing_label' => 'Editar publicaciones existentes',
'update_existing_comment' => 'Selecciona este check para actualizar las publicaciones con exactamente la misma ID, título o URL.',
'auto_create_categories_label' => 'Crear categorías especificadas en el archivo a importar',
'auto_create_categories_comment' => 'Debes hacer coincidir la columna Categoría para usar esta funcionalidad, sino selecciona la categoría por defecto para para usar para los elementos de abajo.',
'categories_label' => 'Categorías',
'categories_comment' => 'Selecciona las categorías a las que pertenecerán las publicaciones importadas (opcional).',
'default_author_label' => 'Autor de publicación por defecto (opcional)',
'default_author_comment' => 'La importación intentará usar un autor existente si coicide con la columna "Author Email", sino se usará el autor especificado arriba.',
'default_author_placeholder' => '-- Selecciona Autor/a --'
]
];

View File

@ -0,0 +1,109 @@
<?php
return [
'plugin' => [
'name' => 'وبلاگ',
'description' => 'پلتفرم قوی برای وبلاگ نویسی'
],
'blog' => [
'menu_label' => 'وبلاگ',
'menu_description' => 'مدیریت پست های ارسالی',
'posts' => 'پست ها',
'create_post' => 'ایجاد پست جدید',
'categories' => 'دسته بندی ها',
'create_category' => 'ایجاد دسته بندی جدید',
'tab' => 'وبلاگ',
'access_posts' => 'مدیریت پست های ارسالی',
'access_categories' => 'مدیریت دسته بندی های وبلاگ',
'access_other_posts' => 'مدیریت پست های ارسالی سایر کاربران',
'access_import_export' => 'توانایی واردکردن و خارج کردن پستها',
'delete_confirm' => 'آیا اطمینان دارید؟',
'chart_published' => 'منتشر شده',
'chart_drafts' => 'پیش نویس',
'chart_total' => 'مجموع'
],
'posts' => [
'list_title' => 'مدیریت پست های ارسالی',
'filter_category' => 'دسته بندی',
'filter_published' => 'مخفی کردن منتشر شده ها',
'new_post' => 'پست جدید'
],
'post' => [
'title' => 'عنوان',
'title_placeholder' => 'عنوان پست جدید',
'content' => 'محتوی',
'content_html' => 'محتوی HTML',
'slug' => 'آدرس',
'slug_placeholder' => 'آدرس-پست-جدید',
'categories' => 'دسته بندی ها',
'author_email' => 'پست الکترونیکی نویسنده',
'created' => 'ایجاد شده در',
'created_date' => 'تاریخ ایجاد',
'updated' => 'به روزرسانی شده در',
'updated_date' => 'تاریخ به روزرسانی',
'published' => 'منتشر شده',
'published_date' => 'تاریخ انتشار',
'published_validation' => 'لطفا تاریخ انتشار را وارد نمایید',
'tab_edit' => 'ویرایش',
'tab_categories' => 'دسته بندی ها',
'categories_comment' => 'دسته بندی هایی را که پست به آنها تعلق دارد را انتخاب نمایید',
'categories_placeholder' => 'دسته بندی ای وجود ندارد. ابتدا یک دسته بندی ایجاد نمایید!',
'tab_manage' => 'مدیریت',
'published_on' => 'منتشر شده در',
'excerpt' => 'خلاصه',
'summary' => 'چکیده',
'featured_images' => 'تصاویر شاخص',
'delete_confirm' => 'آیا از حذف این پست اطمینان دارید؟',
'close_confirm' => 'پست ذخیره نشده است',
'return_to_posts' => 'بازگشت به لیست پست ها'
],
'categories' => [
'list_title' => 'مدیریت دسته بندی های وبلاگ',
'new_category' => 'دسته بندی جدید',
'uncategorized' => 'بدون دسته بندی'
],
'category' => [
'name' => 'نام',
'name_placeholder' => 'نام دسته بندی جدید',
'slug' => 'آدرس',
'slug_placeholder' => 'آدرس-جدید-دسته-بندی',
'posts' => 'پست ها',
'delete_confirm' => 'آیا از حذف این دسته بندی اطمینان دارید؟',
'return_to_categories' => 'بازگشت به لیست دسته بندی های وبلاگ',
'reorder' => 'مرتب سازی دسته بندی ها'
],
'settings' => [
'category_title' => 'لیست دسته بندی',
'category_description' => 'نمایش لیست دسته بندی های وبلاگ در صفحه',
'category_slug' => 'آدرس دسته بندی',
'category_slug_description' => "دسته بندی وبلاگ توسط آدرس وارد شده جستجو می شود. این عمل توسط ابزار دسته بندی برای برجسته ساختن دسته بندی در حال نمایش استفاده می شود.",
'category_display_empty' => 'نمایش دسته بندی های خالی',
'category_display_empty_description' => 'نمایش دسته بندی هایی که هیچ ارسالی در آنها وجود ندارد.',
'category_page' => 'صفحه دسته بندی',
'category_page_description' => 'نام صفحه ای که لیست دسته بندی ها در آن نمایش داده می شوند. این گزینه به طور پیشفرض توسط ابزار مورد استفاده قرار میگیرد.',
'post_title' => 'پست',
'post_description' => 'نمایش پست در صفحه',
'post_slug' => 'آدرس پست',
'post_slug_description' => "پست توسط آدرس وارد شده جستجو میشود.",
'post_category' => 'صفحه دسته بندی',
'post_category_description' => 'نام صفحه ای که لیست دسته بندی ها در آن نمایش داده می شوند. این گزینه به طور پیشفرض توسط ابزار مورد استفاده قرار میگیرد.',
'posts_title' => 'لیست پست ها',
'posts_description' => 'نمایش لیستی از پستهایی که اخیرا ارسال شده اند در صفحه.',
'posts_pagination' => 'شماره صفحه',
'posts_pagination_description' => 'این مقدار جهت تشخیص صفحه ای که کاربر در آن قرار دارد مورد استفاده قرار میگیرد.',
'posts_filter' => 'فیلتر دسته بندی',
'posts_filter_description' => 'آدرس دسته بندی ای را که میخواهید پست های آن نمایش داده شوند را وارد نمایید. اگر میخواهید همه پست ها نمایش داده شوند این مقدار را خالی رها کنید.',
'posts_per_page' => 'تعداد پست ها در هر صفحه',
'posts_per_page_validation' => 'مقدار ورودی تعداد پست ها در هر صفحه نامعتبر است.',
'posts_no_posts' => 'پیغام پستی وجود ندارد',
'posts_no_posts_description' => 'این پیغام در صورتی که پستی جهت نمایش وجود نداشته باشد، نمایش داده می شود.',
'posts_order' => 'ترتیب پست ها',
'posts_order_decription' => 'مشخصه ترتیب نمایش پست ها در صفحه',
'posts_category' => 'صفحه دسته بندی',
'posts_category_description' => 'نام صفحه دسته بندی برای نمایش پستهای مربوط به آن.',
'posts_post' => 'صفحه پست',
'posts_post_description' => 'نام صفحه مربوط به نمایش کامل پست ها جهت لینک ادامه مطلب',
'posts_except_post' => 'Except post',
'posts_except_post_description' => 'Enter ID/URL or variable with post ID/URL you want to except',
]
];

View File

@ -0,0 +1,163 @@
<?php
return [
'plugin' => [
'name' => 'Blogi',
'description' => 'Vankka bloggausalusta.'
],
'blog' => [
'menu_label' => 'Blogi',
'menu_description' => 'Hallitse blogipostauksia',
'posts' => 'Postaukset',
'create_post' => 'Blogipostaus',
'categories' => 'Categories',
'create_category' => 'Blogikategoria',
'tab' => 'Blogi',
'access_posts' => 'Hallitse postauksia',
'access_categories' => 'Hallitse kategorioita',
'access_other_posts' => 'Hallitse muiden käyttäjien postauksia',
'access_import_export' => 'Saa tuoda ja viedä postauksia',
'access_publish' => 'Saa julkaista postauksia',
'manage_settings' => 'Manage blog settings',
'delete_confirm' => 'Olteko varma?',
'chart_published' => 'Julkaistu',
'chart_drafts' => 'Luonnokset',
'chart_total' => 'Yhteensä',
'settings_description' => 'Hallinnoi blogin asetuksia',
'show_all_posts_label' => 'Näytä kaikki postaukset ylläpitäjille',
'show_all_posts_comment' => 'Näytä molemmat sekä julkaistut että julkaisemattomat postaukset ylläpitäjille',
'tab_general' => 'Yleiset'
],
'posts' => [
'list_title' => 'Hallitse blogipostauksia',
'filter_category' => 'Kategoria',
'filter_published' => 'Julkaistu',
'filter_date' => 'Päivämäärä',
'new_post' => 'Uusi postaus',
'export_post' => 'Vie postaukset',
'import_post' => 'Tuo postauksia'
],
'post' => [
'title' => 'Otsikko',
'title_placeholder' => 'Uuden postauksen otsikko',
'content' => 'Sisältö',
'content_html' => 'HTML Sisältö',
'slug' => 'Slugi',
'slug_placeholder' => 'uuden-postaukse-slugi',
'categories' => 'Kategoriat',
'author_email' => 'Tekijän sähköposti',
'created' => 'Luotu',
'created_date' => 'Luomispäivämäärä',
'updated' => 'Muokattu',
'updated_date' => 'Muokkauspäivämäärä',
'published' => 'Julkaistu',
'published_by' => 'Published by',
'current_user' => 'Current user',
'published_date' => 'Julkaisupäivämäärä',
'published_validation' => 'Määrittele julkaisupäivämäärä',
'tab_edit' => 'Muokkaa',
'tab_categories' => 'Kategoriat',
'categories_comment' => 'Valitse kategoriat joihin postaus kuuluu',
'categories_placeholder' => 'Kategorioita ei ole, sinun pitäisi luoda ensimmäinen ensin!',
'tab_manage' => 'Hallitse',
'published_on' => 'Julkaistu',
'excerpt' => 'Poiminto',
'summary' => 'Yhteenveto',
'featured_images' => 'Esittelykuvat',
'delete_confirm' => 'Poista tämä postaus?',
'delete_success' => 'Postaukset poistettu onnistuneesti.',
'close_confirm' => 'Tämä postaus ei ole tallennettu.',
'return_to_posts' => 'Palaa postauslistaan'
],
'categories' => [
'list_title' => 'Hallitse blogikategorioita',
'new_category' => 'Uusi kategoria',
'uncategorized' => 'Luokittelematon'
],
'category' => [
'name' => 'Nimi',
'name_placeholder' => 'Uuden kategorian nimi',
'description' => 'Kuvaus',
'slug' => 'Slugi',
'slug_placeholder' => 'uuden-kategorian-slugi',
'posts' => 'Julkaisuja',
'delete_confirm' => 'Poista tämä kategoria?',
'delete_success' => 'Kategoriat poistettu onnistuneesti.',
'return_to_categories' => 'Palaa blogikategorialistaan',
'reorder' => 'Järjestä kategoriat uudelleen'
],
'menuitem' => [
'blog_category' => 'Blogikategoria',
'all_blog_categories' => 'Kaikki blogikategoriat',
'blog_post' => 'Blogipostaukset',
'all_blog_posts' => 'Kaikki blogipostaukset',
'category_blog_posts' => 'Blogin kategorian postaukset'
],
'settings' => [
'category_title' => 'Kategorialista',
'category_description' => 'Näyttää listan blogikategorioista sivulla.',
'category_slug' => 'Kategorian slugi',
'category_slug_description' => 'Etsii blogikategorian käyttämällä annettua slugi-arvoa. Komponentti käyttää tätä merkitsemään aktiivisen kategorian.',
'category_display_empty' => 'Näytä tyhjät kategoriat',
'category_display_empty_description' => 'Näytä kategoriat joilla ei ole yhtään postauksia.',
'category_page' => 'Kategoriasivu',
'category_page_description' => 'Kategorialistaussivun tiedostonimi. Oletuskomponenttiosa käyttää tätä ominaisuutta.',
'post_title' => 'Postaus',
'post_description' => 'Näyttää blogipostauksen sivulla.',
'post_slug' => 'Postauksen slugi',
'post_slug_description' => 'Etsii blogipostauksen käyttämällä annettua slugi-arvoa.',
'post_category' => 'Kategoriasivu',
'post_category_description' => 'Kategorialistaussivun tiedostonimi. Oletuskomponenttiosa käyttää tätä ominaisuutta.',
'posts_title' => 'Lista postauksista',
'posts_description' => 'Näyttää listan uusimmista blogipostauksista sivulla.',
'posts_pagination' => 'Sivunumero',
'posts_pagination_description' => 'Tätä arvoa käytetään määrittämään millä sivulla käyttäjä on.',
'posts_filter' => 'Kategoriasuodatin',
'posts_filter_description' => 'Lisää kategorian slugi tai URL parametri, jolla suodattaa postauksia. Jätä tyhjäksi näyttääksesi kaikki postaukset.',
'posts_per_page' => 'Postauksia per sivu',
'posts_per_page_validation' => 'Postauksia per sivu -kohta sisältää kelvottoman arvon',
'posts_no_posts' => 'Ei julkaisuja -viesti',
'posts_no_posts_description' => 'Viesti, joka näytetään silloin kun postauksia ei ole. Oletuskomponenttiosa käyttää tätä ominaisuutta.',
'posts_no_posts_default' => 'Ei postauksia',
'posts_order' => 'Postauksien järjestys',
'posts_order_description' => 'Attribuutti, jonka mukaan postaukset tulisi järjestää',
'posts_category' => 'Kategoriasivu',
'posts_category_description' => 'Kategoriasivun tiedosto "Julkaistu kohteeseen" kategorialinkkejä varten. Oletuskomponenttiosa käyttää tätä ominaisuutta.',
'posts_post' => 'Postaussivu',
'posts_post_description' => 'Blogisivun tiedostonimi "Lue lisää" linkkejä varten. Oletuskomponenttiosa käyttää tätä ominaisuutta.',
'posts_except_post' => 'Poissulje postauksia',
'posts_except_post_description' => 'Lisää postauksen ID/URL tai muuttuja, jonka haluat poissulkea',
'posts_except_post_validation' => 'Postaukset poikkeukset täytyy olla yksittäinen slugi tai ID, pilkulla erotettu slugi-lista ja ID:t',
'posts_except_categories' => 'Poikkeavat kategoriat',
'posts_except_categories_description' => 'Lisää pilkulla erotettu listaus kategoria slugeista tai listaus kategorioista jotka haluat jättää ulkopuolelle',
'posts_except_categories_validation' => 'Poikkeavat kategoriat ovat oltava yksittäinen kategoria slugi tai pilkulla erotettu listaus slugeista',
'rssfeed_blog' => 'Blogisivu',
'rssfeed_blog_description' => 'Blogisivun tiedostonimi linkkien generointia varten. Oletuskomponenttiosa käyttää tätä ominaisuutta.',
'rssfeed_title' => 'RSS syöte',
'rssfeed_description' => 'Generoi RSS syötteen sisältäen postaukset blogista.',
'group_links' => 'Linkit',
'group_exceptions' => 'Poikkeukset'
],
'sorting' => [
'title_asc' => 'Otsikko (ascending)',
'title_desc' => 'Otsikko (descending)',
'created_asc' => 'Luotu (ascending)',
'created_desc' => 'Luotu (descending)',
'updated_asc' => 'Päivitetty (ascending)',
'updated_desc' => 'Päivitetty (descending)',
'published_asc' => 'Julkaistu (ascending)',
'published_desc' => 'Julkaistu (descending)',
'random' => 'Satunnainen'
],
'import' => [
'update_existing_label' => 'Päivitä olemassa olevat postaukset',
'update_existing_comment' => 'Valitse tämä laatikko päivittääksesi postaukset, joissa on täsmälleen sama ID, otsikko tai slugi.',
'auto_create_categories_label' => 'Luo tuotavassa tiedostossa määritellyt kategoriat.',
'auto_create_categories_comment' => 'Sinun tulisi yhdistää Kategoriat-sarake käyttääksesi tätä toiminnallisuutta. Muussa tapauksessa valitse oletuskategoria alapuolelta.',
'categories_label' => 'Kategoriat',
'categories_comment' => 'Valitse kategoriat, joihin tuotavat postaukset liitetään (option).',
'default_author_label' => 'Oletuskirjoittaja (optio)',
'default_author_comment' => 'Tuonti yrittää käyttää Kirjoittaja tiedon sähköpostia yhdistäessään kirjoittajaa. Muussa tapauksessa käytetään ylempänä määriteltyä.',
'default_author_placeholder' => '-- valitse kirjoittaja --'
]
];

View File

@ -0,0 +1,163 @@
<?php
return [
'plugin' => [
'name' => 'Blog',
'description' => 'Une plateforme de blog robuste.'
],
'blog' => [
'menu_label' => 'Blog',
'menu_description' => 'Gestion darticles de blog',
'posts' => 'Articles',
'create_post' => 'article de blog',
'categories' => 'Catégories',
'create_category' => 'catégorie darticles',
'tab' => 'Blog',
'access_posts' => 'Gérer les articles',
'access_categories' => 'Gérer les catégories',
'access_other_posts' => 'Gérer les articles dautres utilisateurs',
'access_import_export' => 'Autorisé à importer et exporter des articles',
'access_publish' => 'Autorisé à publier des articles',
'manage_settings' => 'Gérer les paramètres du blog',
'delete_confirm' => 'Confirmez-vous la suppression des articles sélectionnés ?',
'chart_published' => 'Publié',
'chart_drafts' => 'Brouillons',
'chart_total' => 'Total',
'settings_description' => 'Gérer les paramètres du blog',
'show_all_posts_label' => "Afficher tous les messages aux utilisateurs du panneaux d'administration",
'show_all_posts_comment' => 'Afficher autant les publications publiées et non publiées sur le site web pour les utilisateurs principaux',
'tab_general' => 'Général'
],
'posts' => [
'list_title' => 'Gérer les articles du blog',
'filter_category' => 'Catégorie',
'filter_published' => 'Masquer la publication',
'filter_date' => 'Date',
'new_post' => 'Nouvel article',
'export_post' => 'Exporter les articles',
'import_post' => 'Importer des articles'
],
'post' => [
'title' => 'Titre',
'title_placeholder' => 'Titre du nouvel article',
'content' => 'Contenu',
'content_html' => 'Contenu HTML',
'slug' => 'Adresse',
'slug_placeholder' => 'adresse-du-nouvel-article',
'categories' => 'Catégories',
'author_email' => 'Email de lauteur',
'created' => 'Créé',
'created_date' => 'Date de création',
'updated' => 'Mis a jour',
'updated_date' => 'Date de mise à jour',
'published' => 'Publié',
'published_by' => 'Publié par',
'current_user' => 'Utilisateur actuel',
'published_date' => 'Date de publication',
'published_validation' => 'Veuillez préciser la date de publication',
'tab_edit' => 'Rédaction',
'tab_categories' => 'Catégories',
'categories_comment' => 'Sélectionnez les catégories auxquelles larticle est lié',
'categories_placeholder' => 'Il nexiste pas encore de catégorie, mais vous pouvez en créer une !',
'tab_manage' => 'Configuration',
'published_on' => 'Publié le',
'excerpt' => 'Extrait',
'summary' => 'Résumé',
'featured_images' => 'Image de promotion',
'delete_confirm' => 'Confirmez-vous la suppression de cet article ?',
'delete_success' => 'Ces articles ont été supprimés avec succès.',
'close_confirm' => 'Larticle nest pas enregistré.',
'return_to_posts' => 'Retour à la liste des articles'
],
'categories' => [
'list_title' => 'Gérer les catégories',
'new_category' => 'Nouvelle catégorie',
'uncategorized' => 'Non catégorisé'
],
'category' => [
'name' => 'Nom',
'name_placeholder' => 'Nom de la nouvelle catégorie',
'description' => 'Description',
'slug' => 'Adresse URL',
'slug_placeholder' => 'adresse-de-la-nouvelle-catégorie',
'posts' => 'Articles',
'delete_confirm' => 'Confirmez-vous la suppression de cette catégorie ?',
'delete_success' => 'Ces catégories ont été supprimés avec succès.',
'return_to_categories' => 'Retour à la liste des catégories',
'reorder' => 'Réorganiser les catégories'
],
'menuitem' => [
'blog_category' => 'Catégories du blog',
'all_blog_categories' => 'Toutes les catégories du blog',
'blog_post' => 'Articles du blog',
'all_blog_posts' => 'Tous les articles du blog',
'category_blog_posts' => "Articles d'une catégorie du blog"
],
'settings' => [
'category_title' => 'Liste des catégories',
'category_description' => 'Afficher une liste des catégories sur la page.',
'category_slug' => 'Adresse URL de la catégorie',
'category_slug_description' => 'Adresse URL daccès à la catégorie. Cette propriété est utilisée par le partial par défaut du composant pour marquer la catégorie courante comme active.',
'category_display_empty' => 'Afficher les catégories vides.',
'category_display_empty_description' => 'Afficher les catégories qui ne sont liés à aucun article.',
'category_page' => 'Page des catégories',
'category_page_description' => 'Nom de la page des catégories pour les liens de catégories. Cette propriété est utilisée par le partial par défaut du composant.',
'post_title' => 'Article',
'post_description' => 'Affiche un article de blog sur la page.',
'post_slug' => 'Adresse URL de larticle',
'post_slug_description' => 'Adresse URL daccès à larticle.',
'post_category' => 'Page des catégories',
'post_category_description' => 'Nom de la page des catégories pour les liens de catégories. Cette propriété est utilisée par le partial par défaut du composant.',
'posts_title' => 'Liste darticles',
'posts_description' => 'Affiche une liste des derniers articles de blog sur la page.',
'posts_pagination' => 'Numéro de page',
'posts_pagination_description' => 'Cette valeur est utilisée pour déterminer à quelle page lutilisateur se trouve.',
'posts_filter' => 'Filtre des catégories',
'posts_filter_description' => 'Entrez une adresse de catégorie ou un paramètre dURL pour filter les articles. Laissez vide pour afficher tous les articles.',
'posts_per_page' => 'Articles par page',
'posts_per_page_validation' => 'Format du nombre darticles par page incorrect',
'posts_no_posts' => 'Message en labsence darticles',
'posts_no_posts_description' => 'Message à afficher dans la liste darticles lorsquil ny a aucun article. Cette propriété est utilisée par le partial par défaut du composant.',
'posts_no_posts_default' => 'Aucun article trouvé',
'posts_order' => 'Ordre des articles',
'posts_order_description' => 'Attribut selon lequel les articles seront ordonnés',
'posts_category' => 'Page de catégorie',
'posts_category_description' => 'Nom du fichier de la page de catégorie pour les liens de catégorie "Publié dans". Cette propriété est utilisée par le composant par défaut du modèle partiel.',
'posts_post' => "Page de l'article",
'posts_post_description' => 'Nom du fichier de la page de l\'article du blog pour les liens "En savoir plus". Cette propriété est utilisée par le composant par défaut du modèle partiel.',
'posts_except_post' => 'Article exempté',
'posts_except_post_description' => 'Enter ID/URL or variable with post ID/URL you want to except',
'posts_category' => 'Page des catégories',
'posts_category_description' => 'Nom de la page des catégories pour les liens de catégories "Publié dans". Cette propriété est utilisée par le partial par défaut du composant.',
'posts_post' => 'Page darticle',
'posts_post_description' => 'Nom de la page darticles pour les liens "En savoir plus". Cette propriété est utilisée par le partial par défaut du composant.',
'rssfeed_blog' => 'Page du blog',
'rssfeed_blog_description' => 'Nom de la page principale du blog pour générer les liens. Cette propriété est utilisé par le composant dans le partial.',
'rssfeed_title' => 'Flux RSS',
'rssfeed_description' => 'Génère un Flux RSS contenant les articles du blog.',
'group_links' => 'Liens',
'group_exceptions' => 'Exceptions'
],
'sorting' => [
'title_asc' => 'Titre (ascendant)',
'title_desc' => 'Titre (descendant)',
'created_asc' => 'Création le (ascendant)',
'created_desc' => 'Création (descendant)',
'updated_asc' => 'Mise à jour (ascendant)',
'updated_desc' => 'Mise à jour (descendant)',
'published_asc' => 'Publication (ascendant)',
'published_desc' => 'Publication (descendant)',
'random' => 'Aléatoire'
],
'import' => [
'update_existing_label' => 'Mettre à jour les articles existants',
'update_existing_comment' => 'Cochez cette case pour mettre à jour les articles qui ont exactement le même identifiant, titre ou slug.',
'auto_create_categories_label' => "Créer les catégories spécifiées dans le fichier d'importation",
'auto_create_categories_comment' => 'Vous devez faire correspondre la colonne Catégories pour utiliser cette fonctionnalité. Sinon, sélectionnez les catégories par défaut à utiliser parmi les éléments ci-dessous.',
'categories_label' => 'Catégories',
'categories_comment' => 'Sélectionnez les catégories auxquelles appartiendront les articles importées (facultatif).',
'default_author_label' => 'Auteur par défaut (facultatif)',
'default_author_comment' => "L'importation tentera d'utiliser un auteur existant si vous correspondez la colonne Email à l'auteur, sinon l'auteur spécifié ci-dessus sera utilisé.",
'default_author_placeholder' => "-- sélectionnez l'auteur --"
]
];

View File

@ -0,0 +1,166 @@
<?php
return [
'plugin' => [
'name' => 'Blog',
'description' => 'Teljeskörű blog alkalmazás.'
],
'blog' => [
'menu_label' => 'Blog',
'menu_description' => 'Blog bejegyzések kezelése',
'posts' => 'Bejegyzések',
'create_post' => 'blog bejegyzés',
'categories' => 'Kategóriák',
'create_category' => 'blog kategória',
'tab' => 'Blog',
'access_posts' => 'Blog bejegyzések kezelése',
'access_categories' => 'Blog kategóriák kezelése',
'access_other_posts' => 'Más felhasználók bejegyzéseinek kezelése',
'access_import_export' => 'Bejegyzések importálása és exportálása',
'access_publish' => 'Blog bejegyzések közzététele',
'manage_settings' => 'Blog beállítások kezelése',
'delete_confirm' => 'Törölni akarja a kijelölt bejegyzéseket?',
'chart_published' => 'Közzétéve',
'chart_drafts' => 'Piszkozatok',
'chart_total' => 'Összesen',
'settings_description' => 'Beállítási lehetőségek.',
'show_all_posts_label' => 'Az összes bejegyzés mutatása az adminisztrátorok számára',
'show_all_posts_comment' => 'A közzétett és a még nem publikált bejegyzések is egyaránt meg fognak jelenni az oldal szerkesztőinek.',
'tab_general' => 'Általános'
],
'posts' => [
'list_title' => 'Blog bejegyzések',
'filter_category' => 'Kategória',
'filter_published' => 'Közzétéve',
'filter_date' => 'Létrehozva',
'new_post' => 'Új bejegyzés',
'export_post' => 'Exportálás',
'import_post' => 'Importálás'
],
'post' => [
'title' => 'Cím',
'title_placeholder' => 'Új bejegyzés címe',
'content' => 'Szöveges tartalom',
'content_html' => 'HTML tartalom',
'slug' => 'Keresőbarát cím',
'slug_placeholder' => 'uj-bejegyzes-cime',
'categories' => 'Kategóriák',
'author_email' => 'Szerző e-mail címe',
'created' => 'Létrehozva',
'created_date' => 'Létrehozás dátuma',
'updated' => 'Módosítva',
'updated_date' => 'Módosítás dátuma',
'published' => 'Közzétéve',
'published_by' => 'Szerző:',
'current_user' => 'Felhasználó',
'published_date' => 'Közzététel dátuma',
'published_validation' => 'Adja meg a közzététel dátumát',
'tab_edit' => 'Szerkesztés',
'tab_categories' => 'Kategóriák',
'categories_comment' => 'Jelölje be azokat a kategóriákat, melyekbe be akarja sorolni a bejegyzést',
'categories_placeholder' => 'Nincsenek kategóriák, előbb létre kell hoznia egyet!',
'tab_manage' => 'Kezelés',
'published_on' => 'Közzététel dátuma',
'excerpt' => 'Kivonat',
'summary' => 'Összegzés',
'featured_images' => 'Kiemelt képek',
'delete_confirm' => 'Valóban törölni akarja ezt a bejegyzést?',
'delete_success' => 'Sikeresen törölve lettek a bejegyzések.',
'close_confirm' => 'A bejegyzés nem került mentésre.',
'return_to_posts' => 'Vissza a bejegyzésekhez',
'posted_byline' => 'Publikálva: :date, itt: :categories',
'posted_byline_no_categories' => 'Publikálva: :date.',
'date_format' => 'Y.M.d.',
],
'categories' => [
'list_title' => 'Blog kategóriák',
'new_category' => 'Új kategória',
'uncategorized' => 'Nincs kategorizálva'
],
'category' => [
'name' => 'Név',
'name_placeholder' => 'Új kategória neve',
'description' => 'Leírás',
'slug' => 'Keresőbarát cím',
'slug_placeholder' => 'uj-kategoria-neve',
'posts' => 'Bejegyzések',
'delete_confirm' => 'Valóban törölni akarja ezt a kategóriát?',
'delete_success' => 'Sikeresen törölve lettek a kategóriák.',
'return_to_categories' => 'Vissza a kategóriákhoz',
'reorder' => 'Kategóriák sorrendje'
],
'menuitem' => [
'blog_category' => 'Blog kategória',
'all_blog_categories' => 'Összes blog kategória',
'blog_post' => 'Blog bejegyzés',
'all_blog_posts' => 'Összes blog bejegyzés',
'category_blog_posts' => 'Blog kategória bejegyzések'
],
'settings' => [
'category_title' => 'Blog kategória lista',
'category_description' => 'A blog kategóriákat listázza ki a lapon.',
'category_slug' => 'Cím paraméter neve',
'category_slug_description' => 'A webcím útvonal paramétere a jelenlegi kategória keresőbarát címe alapján való kereséséhez. Az alapértelmezett komponensrész ezt a tulajdonságot használja a jelenleg aktív kategória megjelöléséhez.',
'category_display_empty' => 'Üres kategóriák kijelzése',
'category_display_empty_description' => 'Azon kategóriák megjelenítése, melyekben nincs egy bejegyzés sem.',
'category_page' => 'Kategória lap',
'category_page_description' => 'A kategória hivatkozások kategória lap fájljának neve. Az alapértelmezett komponensrész használja ezt a tulajdonságot.',
'post_title' => 'Blog bejegyzés',
'post_description' => 'Egy blog bejegyzést jelez ki a lapon.',
'post_slug' => 'Cím paraméter neve',
'post_slug_description' => 'A webcím útvonal paramétere a bejegyzés keresőbarát címe alapján való kereséséhez.',
'post_category' => 'Kategória lap',
'post_category_description' => 'A kategória hivatkozások kategória lap fájljának neve. Az alapértelmezett komponensrész használja ezt a tulajdonságot.',
'posts_title' => 'Blog bejegyzések',
'posts_description' => 'A közzétett blog bejegyzések listázása a honlapon.',
'posts_pagination' => 'Lapozósáv paraméter neve',
'posts_pagination_description' => 'A lapozósáv lapjai által használt, várt paraméter neve.',
'posts_filter' => 'Kategória szűrő',
'posts_filter_description' => 'Adja meg egy kategória keresőbarát címét vagy webcím paraméterét a bejegyzések szűréséhez. Hagyja üresen az összes bejegyzés megjelenítéséhez.',
'posts_per_page' => 'Bejegyzések laponként',
'posts_per_page_validation' => 'A laponkénti bejegyzések értéke érvénytelen formátumú',
'posts_no_posts' => 'Üzenet ha nincs bejegyzés',
'posts_no_posts_description' => 'A blog bejegyzés listában kijelezendő üzenet abban az esetben, ha nincsenek bejegyzések. Az alapértelmezett komponensrész használja ezt a tulajdonságot.',
'posts_no_posts_default' => 'Nem található bejegyzés',
'posts_order' => 'Bejegyzések sorrendje',
'posts_order_description' => 'Jellemző, ami alapján rendezni kell a bejegyzéseket',
'posts_category' => 'Kategória lap',
'posts_category_description' => 'A "Kategória" kategória hivatkozások kategória lap fájljának neve. Az alapértelmezett komponensrész használja ezt a tulajdonságot.',
'posts_post' => 'Bejegyzéslap',
'posts_post_description' => 'A "Tovább olvasom" hivatkozások blog bejegyzéslap fájljának neve. Az alapértelmezett komponensrész használja ezt a tulajdonságot.',
'posts_except_post' => 'Bejegyzés kizárása',
'posts_except_post_description' => 'Adja meg annak a bejegyzésnek az azonosítóját vagy webcímét, amit nem akar megjeleníteni a listázáskor.',
'posts_except_post_validation' => 'A kivételnek webcímnek, illetve azonosítónak, vagy pedig ezeknek a vesszővel elválasztott felsorolásának kell lennie.',
'posts_except_categories' => 'Kategória kizárása',
'posts_except_categories_description' => 'Adja meg azoknak a kategóriáknak a webcímét vesszővel elválasztva, amiket nem akar megjeleníteni a listázáskor.',
'posts_except_categories_validation' => 'A kivételnek webcímnek, vagy pedig ezeknek a vesszővel elválasztott felsorolásának kell lennie.',
'rssfeed_blog' => 'Blog oldal',
'rssfeed_blog_description' => 'Annak a lapnak a neve, ahol listázódnak a blog bejegyzések. Ezt a beállítást használja alapértelmezetten a blog komponens is.',
'rssfeed_title' => 'RSS hírfolyam',
'rssfeed_description' => 'A bloghoz tartozó RSS hírfolyam generálása.',
'group_links' => 'Hivatkozások',
'group_exceptions' => 'Kivételek'
],
'sorting' => [
'title_asc' => 'Név (növekvő)',
'title_desc' => 'Név (csökkenő)',
'created_asc' => 'Létrehozva (növekvő)',
'created_desc' => 'Létrehozva (csökkenő)',
'updated_asc' => 'Frissítve (növekvő)',
'updated_desc' => 'Frissítve (csökkenő)',
'published_asc' => 'Publikálva (növekvő)',
'published_desc' => 'Publikálva (csökkenő)',
'random' => 'Véletlenszerű'
],
'import' => [
'update_existing_label' => 'Meglévő bejegyzések frissítése',
'update_existing_comment' => 'Két bejegyzés akkor számít ugyanannak, ha megegyezik az azonosító számuk, a címük vagy a webcímük.',
'auto_create_categories_label' => 'Az import fájlban megadott kategóriák létrehozása',
'auto_create_categories_comment' => 'A funkció használatához meg kell felelnie a Kategóriák oszlopnak, különben az alábbi elemekből válassza ki az alapértelmezett kategóriákat.',
'categories_label' => 'Kategóriák',
'categories_comment' => 'Válassza ki azokat a kategóriákat, amelyekhez az importált bejegyzések tartoznak (nem kötelező).',
'default_author_label' => 'Alapértelmezett szerző (nem kötelező)',
'default_author_comment' => 'A rendszer megpróbál egy meglévő felhasználót társítani a bejegyzéshez az Email oszlop alapján. Amennyiben ez nem sikerül, az itt megadott szerzőt fogja alapul venni.',
'default_author_placeholder' => '-- válasszon felhasználót --'
]
];

View File

@ -0,0 +1,107 @@
<?php
return [
'plugin' => [
'name' => 'Blog',
'description' => 'Una solida piattaforma di blogging.'
],
'blog' => [
'menu_label' => 'Blog',
'menu_description' => 'Gestisci i post',
'posts' => 'Post',
'create_post' => 'post del blog',
'categories' => 'Categorie',
'create_category' => 'categorie del blog',
'tab' => 'Blog',
'access_posts' => 'Gestisci i post',
'access_categories' => 'Gestisci le categorie',
'access_other_posts' => 'Gestisci i post di altri utenti',
'access_import_export' => 'Permesso ad importare ed esportare i post',
'delete_confirm' => 'Sei sicuro?',
'chart_published' => 'Pubblicato',
'chart_drafts' => 'Bozze',
'chart_total' => 'Totale'
],
'posts' => [
'list_title' => 'Gestisci i post',
'category' => 'Categoria',
'hide_published' => 'Nascondi pubblicati',
'new_post' => 'Nuovo post'
],
'post' => [
'title' => 'Titolo',
'title_placeholder' => 'Titolo del nuovo post',
'content' => 'Contenuto',
'content_html' => 'Contenuto HTML',
'slug' => 'Slug',
'slug_placeholder' => 'slug-del-nuovo-post',
'categories' => 'Categorie',
'author_email' => 'Email dell\'autore',
'created' => 'Creato',
'created_date' => 'Data di creazione',
'updated' => 'Aggiornato',
'updated_date' => 'Data di aggiornamento',
'published' => 'Pubblicato',
'published_date' => 'Data di pubblicazione',
'published_validation' => 'Per favore fornisci la data di pubblicazione',
'tab_edit' => 'Modifica',
'tab_categories' => 'Categorie',
'categories_comment' => 'Seleziona le categorie a cui appartiene il post',
'categories_placeholder' => 'Non ci sono categorie, per iniziare dovresti crearne una!',
'tab_manage' => 'Gestisci',
'published_on' => 'Pubblicato il',
'excerpt' => 'Estratto',
'summary' => 'Riassunto',
'featured_images' => 'Immagini in evidenza',
'delete_confirm' => 'Vuoi veramente cancellare questo post?',
'close_confirm' => 'Questo post non è salvato.',
'return_to_posts' => 'Ritorna all\'elenco dei post'
],
'categories' => [
'list_title' => 'Gestisci le categorie del blog',
'new_category' => 'Nuova categoria',
'uncategorized' => 'Non categorizzato'
],
'category' => [
'name' => 'Nome',
'name_placeholder' => 'Nome della nuova categoria',
'slug' => 'Slug',
'slug_placeholder' => 'slug-nuova-categoria',
'posts' => 'Post',
'delete_confirm' => 'Vuoi veramente cancellare questa categoria?',
'return_to_categories' => 'Ritorna all\'elenco delle categorie del blog',
'reorder' => 'Riordino Categorie'
],
'settings' => [
'category_title' => 'Elenco Categorie',
'category_description' => 'Mostra un\'elenco delle categorie del blog sulla pagina.',
'category_slug' => 'Slug categoria',
'category_slug_description' => "Cerca la categoria del blog usando lo slug fornito. Questa proprietà è usata dal componente parziale di default per segnare la categoria attualmente usata.",
'category_display_empty' => 'Mostra categorie vuote',
'category_display_empty_description' => 'Mostra categorie che non hanno alcun post.',
'category_page' => 'Pagina delle categorie',
'category_page_description' => 'Nome del file della pagina delle categorie contenente i link delle categorie. Questa proprietà è usata dal componente parziale di default.',
'post_title' => 'Post',
'post_description' => 'Mostra un post sulla pagina.',
'post_slug' => 'Slug del post',
'post_slug_description' => "Cerca il post con lo slug fornito.",
'post_category' => 'Pagina delle categorie',
'post_category_description' => 'Nome del file della pagina delle categorie contenente i link delle categorie. Questa proprietà è usata dal componente parziale di default.',
'posts_title' => 'Elenco dei post',
'posts_description' => 'Mostra un\'elenco degli ultimi post sulla pagina.',
'posts_pagination' => 'Numero di pagina',
'posts_pagination_description' => 'Questo valore è usato per determinare su quale pagina è l\'utente.',
'posts_filter' => 'Filtro delle categorie',
'posts_filter_description' => 'Inserisci lo slug di una categoria o un parametro dell\'URL con il quale filtrare i post. Lascia vuoto per mostrare tutti i post.',
'posts_per_page' => 'Post per pagina',
'posts_per_page_validation' => 'Il valore di post per pagina ha un formato non valido ',
'posts_no_posts' => 'Messaggio per l\'assenza di post',
'posts_no_posts_description' => 'Messaggio da mostrare nell\'elenco dei post in caso non ce ne siano. Questa proprietà è usata dal componente parziale di default.',
'posts_order' => 'Ordine dei post',
'posts_order_description' => 'Attributo sul quale i post dovrebbero esser ordinati',
'posts_category' => 'Pagina delle categorie',
'posts_category_description' => 'Nome del file per la pagina delle categorie per i link "Postato in" alle categorie. Questa proprietà è usata dal componente parziale di default.',
'posts_post' => 'Pagina del post',
'posts_post_description' => 'Nome del file per la pagina del post per i link "Scopri di più". Questa proprietà è usata dal componente parziale di default.'
]
];

View File

@ -0,0 +1,100 @@
<?php
return [
'plugin' => [
'name' => 'ブログ',
'description' => 'ロバストなブログプラットフォームです。'
],
'blog' => [
'menu_label' => 'ブログ',
'menu_description' => 'ブログの投稿管理',
'posts' => '投稿',
'create_post' => '投稿の追加',
'categories' => 'カテゴリ',
'create_category' => 'カテゴリの追加',
'tab' => 'ブログ',
'access_posts' => '投稿の管理',
'access_categories' => 'カテゴリの管理',
'access_other_posts' => '他ユーザーの投稿の管理',
'delete_confirm' => '削除していいですか?',
'chart_published' => '公開済み',
'chart_drafts' => '下書き',
'chart_total' => '合計'
],
'posts' => [
'list_title' => '投稿の管理',
'filter_category' => 'カテゴリ',
'filter_published' => '下書きのみ',
'new_post' => '投稿を追加'
],
'post' => [
'title' => 'タイトル',
'title_placeholder' => 'タイトルを入力してください',
'slug' => 'スラッグ',
'slug_placeholder' => 'new-post-slug123',
'categories' => 'カテゴリ',
'created' => '作成日',
'updated' => '更新日',
'published' => '公開する',
'published_validation' => '投稿の公開日を指定してください。',
'tab_edit' => '編集',
'tab_categories' => 'カテゴリ',
'categories_comment' => '投稿を関連付けるカテゴリを選択してください。(複数選択可)',
'categories_placeholder' => 'まだカテゴリがありません。先に作成してください。',
'tab_manage' => '管理',
'published_on' => '公開日',
'excerpt' => '投稿の抜粋',
'featured_images' => 'アイキャッチ画像',
'delete_confirm' => '削除していいですか?',
'close_confirm' => '投稿は保存されていません。',
'return_to_posts' => '投稿一覧に戻る'
],
'categories' => [
'list_title' => 'カテゴリ管理',
'new_category' => 'カテゴリの追加',
'uncategorized' => '未分類'
],
'category' => [
'name' => '名前',
'name_placeholder' => 'カテゴリ名をつけてください',
'slug' => 'スラッグ',
'slug_placeholder' => 'new-category-slug-123',
'posts' => '投稿数',
'delete_confirm' => '削除していいですか?',
'return_to_categories' => 'カテゴリ一覧に戻る'
],
'settings' => [
'category_title' => 'カテゴリリスト',
'category_description' => 'ページ内にカテゴリリストを表示します。',
'category_slug' => 'カテゴリスラッグ',
'category_slug_description' => "表示するカテゴリのスラッグを指定します。この項目はコンポーネントのデフォルトパーシャルで使用されます。",
'category_display_empty' => '空のカテゴリの表示',
'category_display_empty_description' => 'この項目がチェックされている場合、投稿が0件のカテゴリもリストに表示します。',
'category_page' => 'カテゴリページ',
'category_page_description' => 'カテゴリページへのリンクを生成するために、カテゴリページのファイル名を指定します。この項目はコンポーネントのデフォルトパーシャルで使用されます。',
'post_title' => '投稿',
'post_description' => 'ページ内に投稿を表示します。',
'post_slug' => '投稿スラッグ',
'post_slug_description' => "表示する投稿のスラッグを指定します。特定の投稿のスラッグか、URLパラメータ(:slug)を指定できます。",
'post_category' => 'カテゴリページ',
'post_category_description' => 'カテゴリリンクを生成するために、カテゴリページのファイル名を指定します。拡張子(.htm)は省いてください。この項目はコンポーネントのデフォルトパーシャルで使用されます。',
'posts_title' => '投稿リスト',
'posts_description' => 'ページ内に新しい投稿のリストを表示します。',
'posts_pagination' => 'ページ番号',
'posts_pagination_description' => 'ページ番号を指定します。URLパラメータ(:page)を指定できます。',
'posts_filter' => 'カテゴリフィルタ',
'posts_filter_description' => '投稿リストのフィルタを指定します。カテゴリのスラッグかURLパラメータ(:slug)を指定できます。空の場合、すべての投稿が表示されます。',
'posts_per_page' => '1ページに表示する投稿数を指定します。',
'posts_per_page_validation' => '1ページに表示する投稿数の形式が正しくありません。',
'posts_no_posts' => '0件時メッセージ',
'posts_no_posts_description' => 'この投稿リストが0件の場合に表示するメッセージを指定します。この項目はコンポーネントのデフォルトパーシャルで使用されます。',
'posts_order' => '並び順',
'posts_order_description' => '投稿リスト内の並び順を指定します。',
'posts_category' => 'カテゴリページ',
'posts_category_description' => 'カテゴリリンクを生成するために、カテゴリページのファイル名を指定します。この項目はコンポーネントのデフォルトパーシャルで使用されます。',
'posts_post' => '投稿ページ',
'posts_post_description' => '"Learn more"リンクを生成するため、投稿ページのファイル名を指定します。拡張子(.htm)は省いてください。この項目はコンポーネントのデフォルトパーシャルで使用されます。',
'posts_except_post' => 'Except post',
'posts_except_post_description' => 'Enter ID/URL or variable with post ID/URL you want to except',
]
];

View File

@ -0,0 +1,99 @@
<?php
return [
'plugin' => [
'name' => 'Blogg',
'description' => 'En robust bloggeplattform.',
],
'blog' => [
'menu_label' => 'Blogg',
'menu_description' => 'Administrer blogginnlegg',
'posts' => 'Innlegg',
'create_post' => 'innlegg',
'categories' => 'Kategorier',
'create_category' => 'kategori',
'access_posts' => 'Administrer blogginnleggene',
'access_categories' => 'Administrer bloggkategorier',
'access_other_posts' => 'Administrere andre brukere sine blogginnlegg',
'delete_confirm' => 'Er du sikker?',
'chart_published' => 'Publisert',
'chart_drafts' => 'Utkast',
'chart_total' => 'Totalt',
],
'posts' => [
'list_title' => 'Administrer blogginnlegg',
'filter_category' => 'Kategori',
'filter_published' => 'Skjul publiserte',
'new_post' => 'Nytt innlegg',
],
'post' => [
'title' => 'Tittel',
'title_placeholder' => 'Innleggets tittel',
'slug' => 'Slug',
'slug_placeholder' => 'innleggets-tittel',
'categories' => 'Kategorier',
'created' => 'Opprettet',
'updated' => 'Oppdatert',
'published' => 'Publisert',
'published_validation' => 'Velg en dato når innlegget skal publiseres',
'tab_edit' => 'Endre',
'tab_categories' => 'Kategorier',
'categories_comment' => 'Velg hvilke kategorier innlegget tilhører',
'categories_placeholder' => 'Det finnes ingen kategorier! Vennligst opprett en først.',
'tab_manage' => 'Egenskaper',
'published_on' => 'Publiseringsdato',
'excerpt' => 'Utdrag',
'featured_images' => 'Utvalgte bilder',
'delete_confirm' => 'Vil du virkelig slette dette innlegget?',
'close_confirm' => 'Innlegget er ikke lagret.',
'return_to_posts' => 'Tilbake til innleggsliste',
],
'categories' => [
'list_title' => 'Administrer bloggkategorier',
'new_category' => 'Ny kategori',
'uncategorized' => 'Uten kategori',
],
'category' => [
'name' => 'Navn',
'name_placeholder' => 'Kategoriens navn',
'slug' => 'Slug',
'slug_placeholder' => 'kategoriens-navn',
'posts' => 'Innlegg',
'delete_confirm' => 'Vil du virkelig slette denne kategorien?',
'return_to_categories' => 'Tilbake til kategorilisten',
],
'settings' => [
'category_title' => 'Category List',
'category_description' => 'Displays a list of blog categories on the page.',
'category_slug' => 'Category slug',
'category_slug_description' => "Look up the blog category using the supplied slug value. This property is used by the default component partial for marking the currently active category.",
'category_display_empty' => 'Display empty categories',
'category_display_empty_description' => 'Show categories that do not have any posts.',
'category_page' => 'Category page',
'category_page_description' => 'Name of the category page file for the category links. This property is used by the default component partial.',
'post_title' => 'Post',
'post_description' => 'Displays a blog post on the page.',
'post_slug' => 'Post slug',
'post_slug_description' => "Look up the blog post using the supplied slug value.",
'post_category' => 'Category page',
'post_category_description' => 'Name of the category page file for the category links. This property is used by the default component partial.',
'posts_title' => 'Post List',
'posts_description' => 'Displays a list of latest blog posts on the page.',
'posts_pagination' => 'Page number',
'posts_pagination_description' => 'This value is used to determine what page the user is on.',
'posts_filter' => 'Category filter',
'posts_filter_description' => 'Enter a category slug or URL parameter to filter the posts by. Leave empty to show all posts.',
'posts_per_page' => 'Posts per page',
'posts_per_page_validation' => 'Invalid format of the posts per page value',
'posts_no_posts' => 'No posts message',
'posts_no_posts_description' => 'Message to display in the blog post list in case if there are no posts. This property is used by the default component partial.',
'posts_order' => 'Post order',
'posts_order_description' => 'Attribute on which the posts should be ordered',
'posts_category' => 'Category page',
'posts_category_description' => 'Name of the category page file for the "Posted into" category links. This property is used by the default component partial.',
'posts_post' => 'Post page',
'posts_post_description' => 'Name of the blog post page file for the "Learn more" links. This property is used by the default component partial.',
'posts_except_post' => 'Except post',
'posts_except_post_description' => 'Enter ID/URL or variable with post ID/URL you want to except',
],
];

View File

@ -0,0 +1,113 @@
<?php
return [
'plugin' => [
'name' => 'Blog',
'description' => 'A robust blogging platform.'
],
'blog' => [
'menu_label' => 'Blog',
'menu_description' => 'Beheer blog artikelen',
'posts' => 'Artikelen',
'create_post' => 'Artikel',
'categories' => 'Categorieën',
'create_category' => 'blog categorie',
'tab' => 'Blog',
'access_posts' => 'Blog artikelen beheren',
'access_categories' => 'Blog categorieën beheren',
'access_other_posts' => 'Beheren van blog artikelen van gebruikers',
'access_import_export' => 'Toegang tot importeren en exporteren van artikelen',
'delete_confirm' => 'Weet je het zeker?',
'chart_published' => 'Gepubliceerd',
'chart_drafts' => 'Concepten',
'chart_total' => 'Totaal'
],
'posts' => [
'list_title' => 'Beheren van blog artikelen',
'filter_category' => 'Categorie',
'filter_published' => 'Verberg gepubliceerd',
'new_post' => 'Nieuw artikel'
],
'post' => [
'title' => 'Titel',
'title_placeholder' => 'Titel van artikel',
'content' => 'Inhoud',
'content_html' => 'HTML Inhoud',
'slug' => 'Slug',
'slug_placeholder' => 'nieuw-artikel-slug',
'categories' => 'Categorieën',
'author_email' => 'E-mail auteur',
'created' => 'Aangemaakt',
'created_date' => 'Aangemaakt op',
'updated' => 'Bijgewerkt',
'updated_date' => 'Bijgewerkt op',
'published' => 'Gepubliceerd',
'published_by' => 'Gepubliceerd door',
'current_user' => 'Huidige gebruiker',
'published_date' => 'Gepubliceerd op',
'published_validation' => 'Graag een publicatie datum opgeven',
'tab_edit' => 'Bewerken',
'tab_categories' => 'Categorieën',
'categories_comment' => 'Selecteer een categorie waarbij het artikel hoort',
'categories_placeholder' => 'Er zijn geen categorieën, maak eerst een categorie aan!',
'tab_manage' => 'Beheer',
'published_on' => 'Gepubliceerd op',
'excerpt' => 'Samenvatting',
'summary' => 'Samenvatting',
'featured_images' => 'Uitgelichte afbeelding',
'delete_confirm' => 'Weet je zeker dat je dit artikel wilt verwijderen?',
'close_confirm' => 'Artikel is nog niet opgeslagen.',
'return_to_posts' => 'Terug naar artikel overzicht',
'posted_byline' => 'Gepubliceerd in :categories op :date.',
'posted_byline_no_categories' => 'Gepubliceerd op :date.',
'date_format' => 'd, M, Y',
],
'categories' => [
'list_title' => 'Beheer blog categorieën',
'new_category' => 'Nieuwe categorie',
'uncategorized' => 'Ongecategoriseerd'
],
'category' => [
'name' => 'Naam',
'name_placeholder' => 'Naam categorie',
'slug' => 'Slug',
'slug_placeholder' => 'nieuw-categorie-slug',
'posts' => 'Artikelen',
'delete_confirm' => 'Weet je zeker dat je deze categorie wilt verwijderen?',
'return_to_categories' => 'Terug naar categorie overzicht'
],
'settings' => [
'category_title' => 'Categorie overzicht',
'category_description' => 'Geeft een lijst weer van alle categorieën op de pagina.',
'category_slug' => 'Categorie slug',
'category_slug_description' => 'Haal blog categorie op a.h.v. de opgegeven slug. Deze waarde wordt standaard gebruikt voor de partial om de actieve categorie te markeren.',
'category_display_empty' => 'Geef lege categorieën weer',
'category_display_empty_description' => 'Geef categorieën weer die geen artikelen hebben.',
'category_page' => 'Categorie pagina',
'category_page_description' => 'Naam van categorie pagina bestand voor de categorie links. Deze waarde wordt standaard gebruikt door de partial.',
'post_title' => 'Artikel',
'post_description' => 'Geef een artikel weer op de pagina.',
'post_slug' => 'Artikel slug',
'post_slug_description' => 'Haal een artikel op a.h.v. de opgegeven slug.',
'post_category' => 'Categorie pagina',
'post_category_description' => 'Naam van categorie pagina bestand voor de categorie links. Deze waarde wordt standaard gebruikt door de partial.',
'posts_title' => 'Artikel overzicht',
'posts_description' => 'Geeft een lijst van de nieuwste artikelen weer op de pagina.',
'posts_pagination' => 'Pagina nummer',
'posts_pagination_description' => 'Deze waarde wordt gebruikt om te kijken op welke pagina de gebruiker is.',
'posts_filter' => 'Categorie filter',
'posts_filter_description' => 'Geef een categorie slug of URL param om de artikelen hier op te kunnen filteren. Leeg laten als alle artikelen getoond moeten worden.',
'posts_per_page' => 'Artikelen per pagina',
'posts_per_page_validation' => 'Ongeldig formaat voor het aantal artikelen per pagina',
'posts_no_posts' => 'Geen artikelen melding',
'posts_no_posts_description' => 'Deze tekst wordt getoond als er geen artikelen zijn. Deze waarde wordt standaard gebruikt door de partial.',
'posts_order' => 'Volgorde artikelen',
'posts_order_description' => 'Kolom waar de artikelen op gesorteerd moeten worden',
'posts_category' => 'Categorie pagina',
'posts_category_description' => 'Naam van categorie pagina bestand voor gekoppeld artikel overzichts pagina. Deze waarde wordt standaard gebruikt door de partial.',
'posts_post' => 'Artikel pagina',
'posts_post_description' => 'Naam van blog pagina bestand voor de "Lees meer" links. Deze waarde wordt standaard gebruikt door de partial.',
'posts_except_post' => 'Except post',
'posts_except_post_description' => 'Enter ID/URL or variable with post ID/URL you want to except',
]
];

View File

@ -0,0 +1,159 @@
<?php return [
'plugin' => [
'name' => 'Blog',
'description' => 'Solidna platforma blogera',
],
'blog' => [
'menu_label' => 'Blog',
'menu_description' => 'Zarządzaj postami na blogu',
'posts' => 'Posty',
'create_post' => 'Utwórz post',
'categories' => 'Kategorie',
'create_category' => 'Utwórz kategorię',
'tab' => 'Blog',
'access_posts' => 'Zarządzaj postami',
'access_categories' => 'Zarządzaj kategoriami na blogu',
'access_other_posts' => 'Zarządzaj postami innych użytkowników',
'access_import_export' => 'Zarządzaj importowaniem i eksportowaniem postów',
'access_publish' => 'Publikuj posty',
'manage_settings' => 'Zarządzaj ustawieniami bloga',
'delete_confirm' => 'Czy jesteś pewien?',
'chart_published' => 'Opublikowane',
'chart_drafts' => 'Szkice',
'chart_total' => 'Łącznie',
'settings_description' => 'Zarządzaj ustawieniami bloga',
'show_all_posts_label' => 'Pokaż wszystkie posty użytkownikom backendu',
'show_all_posts_comment' => 'Wyświetl opublikowane i nieopublikowany posty na stronie dla użytkowników backendu',
'tab_general' => 'Ogólne',
],
'posts' => [
'list_title' => 'Zarządzaj postami',
'filter_category' => 'Kategoria',
'filter_published' => 'Ukryj opublikowane',
'filter_date' => 'Date',
'new_post' => 'Nowy post',
'export_post' => 'Eksportuj posty',
'import_post' => 'Importuj posty',
],
'post' => [
'title' => 'Tytuł',
'title_placeholder' => 'Tytuł nowego posta',
'content' => 'Zawartość',
'content_html' => 'Zawartość HTML',
'slug' => 'Alias',
'slug_placeholder' => 'alias-nowego-postu',
'categories' => 'Kategorie',
'author_email' => 'Email autora',
'created' => 'Utworzony',
'created_date' => 'Data utworzenia',
'updated' => 'Zaktualizowany',
'updated_date' => 'Data aktualizacji',
'published' => 'Opublikowany',
'published_date' => 'Data publikacji',
'published_validation' => 'Proszę określić datę publikacji',
'tab_edit' => 'Edytuj',
'tab_categories' => 'Kategorie',
'categories_comment' => 'Wybierz kategorie do których post należy',
'categories_placeholder' => 'Nie ma żadnej kategorii, powinieneś utworzyć przynajmniej jedną.',
'tab_manage' => 'Zarządzaj',
'published_on' => 'Opublikowane',
'excerpt' => 'Zalążek',
'summary' => 'Summary',
'featured_images' => 'Załączone grafiki',
'delete_confirm' => 'Czy naprawdę chcesz usunąć ten post?',
'delete_success' => 'Posty zostały pomyślnie usunięte.',
'close_confirm' => 'Ten post nie jest zapisany.',
'return_to_posts' => 'Wróć do listy postów',
],
'categories' => [
'list_title' => 'Zarządzaj kategoriami postów',
'new_category' => 'Nowa kategoria',
'uncategorized' => 'Bez kategorii',
],
'category' => [
'name' => 'Nazwa',
'name_placeholder' => 'Nazwa nowej kategorii',
'description' => 'Opis',
'slug' => 'Alias',
'slug_placeholder' => 'alias-nowej-kategorii',
'posts' => 'Posty',
'delete_confirm' => 'Czy naprawdę chcesz usunąć tę kategorię?',
'delete_success' => 'Kategorie zostały pomyślnie usunięte.',
'return_to_categories' => 'Wróć do listy kategorii',
'reorder' => 'Zmień kolejnośc kategorii',
],
'menuitem' => [
'blog_category' => 'Kategorie',
'all_blog_categories' => 'Wszystkie kategorie',
'blog_post' => 'Post na bloga',
'all_blog_posts' => 'Wszystkie posty',
'category_blog_posts' => 'Posty w kategorii',
],
'settings' => [
'category_title' => 'Lista kategorii',
'category_description' => 'Wyświetla listę blogowych kategorii na stronie.',
'category_slug' => 'Alias kategorii',
'category_slug_description' => 'Look up the blog category using the supplied slug value. This property is used by the default component partial for marking the currently active category.',
'category_display_empty' => 'Pokaż puste kategorie',
'category_display_empty_description' => 'Pokazuje kategorie, które nie posiadają postów',
'category_page' => 'Strona kategorii',
'category_page_description' => 'Nazwa strony kategorii gdzie są pokazywane linki. Ten parametr jest domyślnie używany przez komponent.',
'post_title' => 'Post',
'post_description' => 'Wyświetla pojedynczy post na stronie.',
'post_slug' => 'Alias postu',
'post_slug_description' => 'Szuka post po nazwie aliasu.',
'post_category' => 'Strona kategorii',
'post_category_description' => 'Nazwa strony kategorii gdzie są pokazywane linki. Ten parametr jest domyślnie używany przez komponent.',
'posts_title' => 'Lista postów',
'posts_description' => 'Wyświetla kilka ostatnich postów.',
'posts_pagination' => 'Numer strony',
'posts_pagination_description' => 'Ta wartość odpowiada za odczytanie numeru strony.',
'posts_filter' => 'Filtr kategorii',
'posts_filter_description' => 'Wprowadź alias kategorii lub adres URL aby filtrować posty. Pozostaw puste aby pokazać wszystkie.',
'posts_per_page' => 'Ilość postów na strone',
'posts_per_page_validation' => 'Nieprawidłowa wartość ilości postów na strone',
'posts_no_posts' => 'Komunikat o braku postów',
'posts_no_posts_description' => 'Wiadomość, która ukaże się kiedy komponent nie odnajdzie postów. Ten parametr jest domyślnie używany przez komponent.',
'posts_no_posts_default' => 'Nie znaleziono postów',
'posts_order' => 'Kolejność postów',
'posts_order_description' => 'Parametr przez który mają być sortowane posty',
'posts_category' => 'Strona kategorii',
'posts_category_description' => 'Nazwa strony kategorii w wyświetlaniu linków "Posted into" [Opublikowano w]. Ten parametr jest domyślnie używany przez komponent.',
'posts_post' => 'Strona postu',
'posts_post_description' => 'Nazwa strony postu dla linków "Learn more" [Czytaj więcej]. Ten parametr jest domyślnie używany przez komponent.',
'posts_except_post' => 'Wyklucz posty',
'posts_except_post_description' => 'Wprowadź ID/URL lub zmienną z ID/URL postu, który chcesz wykluczyć',
'posts_except_post_validation' => 'Wartość pola wykluczenia postów musi być pojedynczym ID/aliasem lub listą ID/aliasów rozdzieloną przecinkami',
'posts_except_categories' => 'Wyklucz kategorie',
'posts_except_categories_description' => 'Wprowadź listę aliasów kategorii rozdzieloną przecinkami lub zmienną zawierającą taką listę',
'posts_except_categories_validation' => 'Wartośc pola wykluczenia kategorii musi być pojedynczym aliasem lub listą aliasów rozdzielonych przecinkami',
'rssfeed_blog' => 'Strona bloga',
'rssfeed_blog_description' => 'Nazwa strony głównej bloga do generowania linków. Używane przez domyślny fragment komponentu.',
'rssfeed_title' => 'Kanał RSS',
'rssfeed_description' => 'Generuje kanał RSS zawierający posty z bloga.',
'group_links' => 'Linki',
'group_exceptions' => 'Wyjątki',
],
'sorting' => [
'title_asc' => 'Tytuł (rosnąco)',
'title_desc' => 'Tytuł (malejąco)',
'created_asc' => 'Data utworzenia (rosnąco)',
'created_desc' => 'Data utworzenia (rosnąco)',
'updated_asc' => 'Data aktualizacji (rosnąco)',
'updated_desc' => 'Data aktualizacji (rosnąco)',
'published_asc' => 'Data publikacji (rosnąco)',
'published_desc' => 'Data publikacji (rosnąco)',
'random' => 'Losowo',
],
'import' => [
'update_existing_label' => 'Aktualizuj istniejące wpisy',
'update_existing_comment' => 'Zaznacz to pole, aby zaktualizować posty, które mają taki sam identyfikator (ID), tytuł lub alias.',
'auto_create_categories_label' => 'Utwórz kategorie podane w pliku',
'auto_create_categories_comment' => 'Aby skorzystać z tej funkcji powinieneś dopasować kolumnę Kategorii. W przeciwnym wypadku wybierz domyślną kategorię do użycia poniżej.',
'categories_label' => 'Kategorie',
'categories_comment' => 'Wybierz kategorię, do której będą należeć zaimportowane posty (opcjonalne).',
'default_author_label' => 'Domyślny autor postów (opcjonalne)',
'default_author_comment' => 'Import spróbuje dopasować istniejącego autora na podstawie kolumny email. W przypadku niepowodzenia zostanie użyty autor wybrany powyżej.',
'default_author_placeholder' => '-- wybierz autora --',
],
];

View File

@ -0,0 +1,124 @@
<?php
return [
'plugin' => [
'name' => 'Blog',
'description' => 'A plataforma de blogs robusta.'
],
'blog' => [
'menu_label' => 'Blog',
'menu_description' => 'Gerencie os posts do blog',
'posts' => 'Posts',
'create_post' => 'Blog post',
'categories' => 'Categorias',
'create_category' => 'Blog categoria',
'tab' => 'Blog',
'access_posts' => 'Gerencie os posts do blog',
'access_categories' => 'Gerenciar as categorias de blog',
'access_other_posts' => 'Gerencie outros posts de usuários do blog',
'access_import_export' => 'Permissão para importação e exportação de mensagens',
'access_publish' => 'Permitido publicar posts',
'delete_confirm' => 'Você tem certeza?',
'chart_published' => 'Publicados',
'chart_drafts' => 'Rascunhos',
'chart_total' => 'Total'
],
'posts' => [
'list_title' => 'Gerencie os posts do blog',
'filter_category' => 'Categoria',
'filter_published' => 'Esconder publicados',
'filter_date' => 'Data',
'new_post' => 'Novo post',
'export_post' => 'Exportar posts',
'import_post' => 'Importar posts'
],
'post' => [
'title' => 'Título',
'title_placeholder' => 'Novo título do post',
'content' => 'Conteúdo',
'content_html' => 'HTML Conteúdo',
'slug' => 'Slug',
'slug_placeholder' => 'slug-do-post',
'categories' => 'Categorias',
'author_email' => 'Autor Email',
'created' => 'Criado',
'created_date' => 'Data de criação',
'updated' => 'Atualizado',
'updated_date' => 'Data de atualização',
'published' => 'Publicado',
'published_date' => 'Data de publicação',
'published_validation' => 'Por favor, especifique a data de publicação',
'tab_edit' => 'Editar',
'tab_categories' => 'Categorias',
'categories_comment' => 'Selecione as categorias do blog que o post pertence.',
'categories_placeholder' => 'Não há categorias, você deve criar um primeiro!',
'tab_manage' => 'Gerenciar',
'published_on' => 'Publicado em',
'excerpt' => 'Resumo',
'summary' => 'Resumo',
'featured_images' => 'Imagens destacadas',
'delete_confirm' => 'Você realmente deseja excluir este post?',
'close_confirm' => 'O post não foi salvo.',
'return_to_posts' => 'Voltar à lista de posts'
],
'categories' => [
'list_title' => 'Gerenciar as categorias do blog',
'new_category' => 'Nova categoria',
'uncategorized' => 'Sem categoria'
],
'category' => [
'name' => 'Nome',
'name_placeholder' => 'Novo nome para a categoria',
'description' => 'Descrição',
'slug' => 'Slug',
'slug_placeholder' => 'novo-slug-da-categoria',
'posts' => 'Posts',
'delete_confirm' => 'Você realmente quer apagar esta categoria?',
'return_to_categories' => 'Voltar para a lista de categorias do blog',
'reorder' => 'Reordenar Categorias'
],
'menuitem' => [
'blog_category' => 'Blog categoria',
'all_blog_categories' => 'Todas as categorias de blog',
'blog_post' => 'Blog post',
'all_blog_posts' => 'Todas as postagens do blog'
],
'settings' => [
'category_title' => 'Lista de categoria',
'category_description' => 'Exibe uma lista de categorias de blog na página.',
'category_slug' => 'Slug da categoria',
'category_slug_description' => "Olhe para cima, a categoria do blog já está usando o valor fornecido! Esta propriedade é usada pelo componente default parcial para a marcação da categoria atualmente ativa.",
'category_display_empty' => 'xibir categorias vazias',
'category_display_empty_description' => 'Mostrar categorias que não tem nenhum post.',
'category_page' => 'Página da categoria',
'category_page_description' => 'Nome do arquivo de página da categoria para os links de categoria. Esta propriedade é usada pelo componente default parcial.',
'post_title' => 'Post',
'post_description' => 'Exibe um post na página.',
'post_slug' => 'Post slug',
'post_slug_description' => "Procure o post do blog usando o valor do slug fornecido.",
'post_category' => 'Página da categoria',
'post_category_description' => 'Nome do arquivo de página da categoria para os links de categoria. Esta propriedade é usada pelo componente default parcial.',
'posts_title' => 'Lista de posts',
'posts_description' => 'Exibe uma lista de últimas postagens na página.',
'posts_pagination' => 'Número da pagina',
'posts_pagination_description' => 'Esse valor é usado para determinar qual página o usuário está.',
'posts_filter' => 'Filtro de categoria',
'posts_filter_description' => 'Digite um slug de categoria ou parâmetro de URL para filtrar as mensagens. Deixe em branco para mostrar todas as mensagens.',
'posts_per_page' => 'Posts por página',
'posts_per_page_validation' => 'Formato inválido das mensagens por valor de página',
'posts_no_posts' => 'Nenhuma mensagem de posts',
'posts_no_posts_description' => 'Mensagem para exibir na lista post no caso, se não há mensagens. Esta propriedade é usada pelo componente default parcial.',
'posts_order' => 'Orde posts',
'posts_order_decription' => 'Atributo em que as mensagens devem ser ordenados',
'posts_category' => 'Página de Categoria',
'posts_category_description' => 'Nome do arquivo de página da categoria para os links de categoria. Esta propriedade é usada pelo componente default parcial.',
'posts_post' => 'Página de posts',
'posts_post_description' => 'Nome do arquivo post página para os "Saiba mais" links. Esta propriedade é usada pelo componente default parcial.',
'posts_except_post' => 'Except post',
'posts_except_post_description' => 'Enter ID/URL or variable with post ID/URL you want to except',
'rssfeed_blog' => 'Página do Blog',
'rssfeed_blog_description' => 'Nome do arquivo principal da página do blog para geração de links. Essa propriedade é usada pelo componente padrão parcial.',
'rssfeed_title' => 'RSS Feed',
'rssfeed_description' => 'Gera um feed RSS que contém posts do blog.'
]
];

View File

@ -0,0 +1,159 @@
<?php
return [
'plugin' => [
'name' => 'Блог',
'description' => 'Надежная блоговая-платформа.'
],
'blog' => [
'menu_label' => 'Блог',
'menu_description' => 'Управление Блогом',
'posts' => 'Записи',
'create_post' => 'записи',
'categories' => 'Категории',
'create_category' => 'категории',
'tab' => 'Блог',
'access_posts' => 'Управление записями блога',
'access_categories' => 'Управление категориями блога',
'access_other_posts' => 'Управление записями других пользователей',
'access_import_export' => 'Разрешено импортировать и экспортировать записи',
'access_publish' => 'Разрешено публиковать записи',
'manage_settings' => 'Управление настройками блога',
'delete_confirm' => 'Вы уверены, что хотите сделать это?',
'chart_published' => 'Опубликовано',
'chart_drafts' => 'Черновики',
'chart_total' => 'Всего',
'settings_description' => 'Управление настройками блога',
'show_all_posts_label' => 'Показывать все записи для внутренних (бэкенд) пользователей',
'show_all_posts_comment' => 'Показывать опубликованные и неопубликованные записи на фронтенде для внутренних (бэкенд) пользователей',
'tab_general' => 'Основные'
],
'posts' => [
'list_title' => 'Управление записями блога',
'filter_category' => 'Категория',
'filter_published' => 'Скрыть опубликованные',
'filter_date' => 'Дата',
'new_post' => 'Новая запись',
'export_post' => 'Экспорт записей',
'import_post' => 'Импорт записей'
],
'post' => [
'title' => 'Заголовок',
'title_placeholder' => 'Новый заголовок записи',
'content' => 'Контент',
'content_html' => 'HTML Контент',
'slug' => 'URL записи',
'slug_placeholder' => 'new-post-slug',
'categories' => 'Категории',
'author_email' => 'Email автора',
'created' => 'Создано',
'created_date' => 'Дата создания',
'updated' => 'Обновлено',
'updated_date' => 'Дата обновления',
'published' => 'Опубликовано',
'published_date' => 'Дата публикации',
'published_validation' => 'Пожалуйста, укажите дату публикации.',
'tab_edit' => 'Редактор',
'tab_categories' => 'Категории',
'categories_comment' => 'Выберите категории, к которым относится эта запись',
'categories_placeholder' => 'Не найдено ни одной категории, создайте хотя бы одну!',
'tab_manage' => 'Управление',
'published_on' => 'Опубликовано',
'excerpt' => 'Отрывок',
'summary' => 'Резюме',
'featured_images' => 'Тематические изображения',
'delete_confirm' => 'Вы действительно хотите удалить эту запись?',
'delete_success' => 'Эти записи успешно удалены.',
'close_confirm' => 'Запись не была сохранена.',
'return_to_posts' => 'Вернуться к списку записей'
],
'categories' => [
'list_title' => 'Управление категориями блога',
'new_category' => 'Новая категория',
'uncategorized' => 'Без категории'
],
'category' => [
'name' => 'Название',
'name_placeholder' => 'Новое имя категории',
'description' => 'Описание',
'slug' => 'URL адрес',
'slug_placeholder' => 'new-category-slug',
'posts' => 'Записи',
'delete_confirm' => 'Вы действительно хотите удалить эту категорию?',
'delete_success' => 'Эти категории успешно удалены.',
'return_to_categories' => 'Вернуться к списку категорий',
'reorder' => 'Порядок категорий'
],
'menuitem' => [
'blog_category' => 'Категория блога',
'all_blog_categories' => 'Все категории блога',
'blog_post' => 'Запись блога',
'all_blog_posts' => 'Все записи блога',
'category_blog_posts' => 'Записи категории блога'
],
'settings' => [
'category_title' => 'Список категорий блога',
'category_description' => 'Отображает список категорий на странице.',
'category_slug' => 'Параметр URL',
'category_slug_description' => 'Параметр маршрута, используемый для поиска в текущей категории по URL. Это свойство используется по умолчанию компонентом Фрагменты для маркировки активной категории.',
'category_display_empty' => 'Пустые категории',
'category_display_empty_description' => 'Отображать категории, которые не имеют записей.',
'category_page' => 'Страница категорий',
'category_page_description' => 'Название страницы категорий. Это свойство используется по умолчанию компонентом Фрагменты.',
'post_title' => 'Запись блога',
'post_description' => 'Отображение записи блога',
'post_slug' => 'Параметр URL',
'post_slug_description' => 'Параметр маршрута, необходимый для выбора конкретной записи.',
'post_category' => 'Страница категорий',
'post_category_description' => 'Название страницы категорий. Это свойство используется по умолчанию компонентом Фрагменты.',
'posts_title' => 'Список записей блога',
'posts_description' => 'Отображает список последних записей блога на странице.',
'posts_pagination' => 'Параметр постраничной навигации',
'posts_pagination_description' => 'Параметр, необходимый для постраничной навигации.',
'posts_filter' => 'Фильтр категорий',
'posts_filter_description' => 'Введите URL категории или параметр URL-адреса для фильтрации записей. Оставьте пустым, чтобы посмотреть все записи.',
'posts_per_page' => 'Записей на странице',
'posts_per_page_validation' => 'Недопустимый Формат. Ожидаемый тип данных - действительное число.',
'posts_no_posts' => 'Отсутствие записей',
'posts_no_posts_description' => 'Сообщение, отображаемое в блоге, если отсутствуют записи. Это свойство используется по умолчанию компонентом Фрагменты.',
'posts_no_posts_default' => 'Записей не найдено',
'posts_order' => 'Сортировка',
'posts_order_description' => 'Атрибут, по которому будут сортироваться записи.',
'posts_category' => 'Страница категорий',
'posts_category_description' => 'Название категории на странице записи "размещена в категории". Это свойство используется по умолчанию компонентом Фрагменты.',
'posts_post' => 'Страница записи',
'posts_post_description' => 'Название страницы для ссылки "подробнее". Это свойство используется по умолчанию компонентом Фрагменты.',
'posts_except_post' => 'Кроме записи',
'posts_except_post_description' => 'Введите ID/URL или переменную с ID/URL записи, которую вы хотите исключить',
'posts_except_categories' => 'Кроме категорий',
'posts_except_categories_description' => 'Введите разделенный запятыми список URL категорий или переменную со списком категорий, которые вы хотите исключить',
'rssfeed_blog' => 'Страница блога',
'rssfeed_blog_description' => 'Имя основного файла страницы блога для генерации ссылок. Это свойство используется по умолчанию компонентом Фрагменты.',
'rssfeed_title' => 'RSS Feed',
'rssfeed_description' => 'Создает RSS-канал, содержащий записи из блога.',
'group_links' => 'Ссылки',
'group_exceptions' => 'Исключения'
],
'sorting' => [
'title_asc' => 'Заголовок (по возрастанию)',
'title_desc' => 'Заголовок (по убыванию)',
'created_asc' => 'Создано (по возрастанию)',
'created_desc' => 'Создано (по убыванию)',
'updated_asc' => 'Обновлено (по возрастанию)',
'updated_desc' => 'Обновлено (по убыванию)',
'published_asc' => 'Опубликовано (по возрастанию)',
'published_desc' => 'Опубликовано (по убыванию)',
'random' => 'Случайно'
],
'import' => [
'update_existing_label' => 'Обновить существующие записи',
'update_existing_comment' => 'Установите этот флажок, чтобы обновлять записи имеющие одинаковый ID, title или URL.',
'auto_create_categories_label' => 'Создать категории указанные в импортируемом файле',
'auto_create_categories_comment' => 'Вы должны сопоставить столбец Категории, чтобы использовать эту функцию. В противном случае выберите для назначения категорию по умолчанию из пунктов ниже.',
'categories_label' => 'Категории',
'categories_comment' => 'Выберите категории, к которым будут принадлежать импортированные записи (необязательно).',
'default_author_label' => 'Автор записи по умолчанию (необязательно)',
'default_author_comment' => 'Импорт попытается использовать существующего автора, если он соответствуете столбцу Email автора, в противном случае используется указанный выше автор.',
'default_author_placeholder' => '-- выберите автора --'
]
];

View File

@ -0,0 +1,154 @@
<?php
return [
'plugin' => [
'name' => 'Blog',
'description' => 'Robustná blogová platforma.'
],
'blog' => [
'menu_label' => 'Blog',
'menu_description' => 'Správa blogových príspevkov',
'posts' => 'Príspevky',
'create_post' => 'Príspevok',
'categories' => 'Kategórie',
'create_category' => 'Kategórie príspevkov',
'tab' => 'Blog',
'access_posts' => 'Správa blogových príspevkov',
'access_categories' => 'Správa blogových kategórií',
'access_other_posts' => 'Správa blogových príspevkov ostatných užívateľov',
'access_import_export' => 'Možnosť importu a exportu príspevkov',
'access_publish' => 'Možnosť publikovať príspevky',
'delete_confirm' => 'Ste si istý?',
'chart_published' => 'PublikovanéPublished',
'chart_drafts' => 'Koncepty',
'chart_total' => 'Celkom'
],
'posts' => [
'list_title' => 'Správa blogových príspevkov',
'filter_category' => 'Kategória',
'filter_published' => 'Publikované',
'filter_date' => 'Dátum',
'new_post' => 'Nový príspevok',
'export_post' => 'Exportovať príspevky',
'import_post' => 'Importovať príspevky'
],
'post' => [
'title' => 'Názov',
'title_placeholder' => 'Názov nového príspevku',
'content' => 'Obsah',
'content_html' => 'HTML Obsah',
'slug' => 'URL príspevku',
'slug_placeholder' => 'url-nového-príspevku',
'categories' => 'Kategórie',
'author_email' => 'Email autora',
'created' => 'Vytvorené',
'created_date' => 'Dátum vytvorenia',
'updated' => 'Upravené',
'updated_date' => 'Dátum upravenia',
'published' => 'Publikované',
'published_date' => 'Dátum publikovania',
'published_validation' => 'Prosím zvoľte dátum publikovania príspevku',
'tab_edit' => 'Upraviť',
'tab_categories' => 'Kategórie',
'categories_comment' => 'Vyberte kategórie do ktorých tento príspevok patrí',
'categories_placeholder' => 'Neexistujú žiadne kategórie, najprv nejakú vytvorte!',
'tab_manage' => 'Nastavenia',
'published_on' => 'Dátum publikovania',
'excerpt' => 'Výňatok príspevku',
'summary' => 'Zhrnutie',
'featured_images' => 'Obrázky',
'delete_confirm' => 'Zmazať tento príspevok?',
'delete_success' => 'Vybrané príspevky boli úspešne odstránené.',
'close_confirm' => 'Príspevok nie je uložený.',
'return_to_posts' => 'Späť na zoznam príspevkov'
],
'categories' => [
'list_title' => 'Správa blogových kategórií',
'new_category' => 'Nová kategória',
'uncategorized' => 'Nezaradené'
],
'category' => [
'name' => 'Názov',
'name_placeholder' => 'Názov novej kategórie',
'description' => 'Popis',
'slug' => 'URL kategórie',
'slug_placeholder' => 'url-novej-kategórie',
'posts' => 'Počet príspevkov',
'delete_confirm' => 'Zmazať túto kategóriu?',
'delete_success' => 'Vybrané kategórie boli úspešne odstránené.',
'return_to_categories' => 'Späť na zoznam kategórií',
'reorder' => 'Zmeniť poradie kategórií'
],
'menuitem' => [
'blog_category' => 'Blogová kategória',
'all_blog_categories' => 'Všetky blogové kategórie',
'blog_post' => 'Blogové príspevky',
'all_blog_posts' => 'Všetky blogové príspevky',
'category_blog_posts' => 'Blogové príspevky v kategórií'
],
'settings' => [
'category_title' => 'Zoznam kategórií',
'category_description' => 'Zobrazí zoznam blogových kategórií na stránke.',
'category_slug' => 'URL kategórie',
'category_slug_description' => "Nájde blogovú kategóriu s týmto URL. Používa sa pre zobrazenie aktívnej kategórie.",
'category_display_empty' => 'Zobraziť prázdne kategórie',
'category_display_empty_description' => 'Zobrazí kategórie, ktoré nemajú žiadne príspevky.',
'category_page' => 'Stránka kategórie',
'category_page_description' => 'Názov stránky kategórie kam budú smerovať odkazy na kategóriu. Táto hodnota je použitá v predvolenej čiastočnej stránke komponentu.',
'post_title' => 'Príspevok',
'post_description' => 'Zobrazí blogový príspevok na stránke.',
'post_slug' => 'URL príspevku',
'post_slug_description' => "Nájde blogový príspevok s týmto URL.",
'post_category' => 'Stránka kategórie',
'post_category_description' => 'Názov stránky kategórie kam budú smerovať odkazy na kategóriu. Táto hodnota je použitá v predvolenej čiastočnej stránke komponentu.',
'posts_title' => 'Zoznam príspevkov',
'posts_description' => 'Zobrazí zoznam blogových príspevkov na stránke.',
'posts_pagination' => 'číslo stránky',
'posts_pagination_description' => 'Táto hodnota je použitá na určenie na akej stránke sa užívateľ nachádza.',
'posts_filter' => 'Filter kategórií',
'posts_filter_description' => 'Zadajte URL kategórie alebo URL parameter na filtrovanie príspevkov. Nechajte prázdne pre zobrazenie všetkých príspevkov.',
'posts_per_page' => 'Príspevkov na stránku',
'posts_per_page_validation' => 'Neplatný formát hodnoty počtu príspevkov na stránku',
'posts_no_posts' => 'Správa prázdnej stránky',
'posts_no_posts_description' => 'Správa, ktorá bude zobrazená v zozname príspevkov v prípade, že nie sú žiadne na zobrazenie. Táto hodnota je použitá v predvolenej čiastočnej stránke komponentu.',
'posts_no_posts_default' => 'Nenašli sa žiadne príspevky',
'posts_order' => 'Zoradenie príspevkov',
'posts_order_description' => 'Atribút podľa ktorého budú príspevky zoradené',
'posts_category' => 'Stránka kategórie',
'posts_category_description' => 'Názov stránky kategórie kam budú smerovať odkazy "Vložené do". Táto hodnota je použitá v predvolenej čiastočnej stránke komponentu.',
'posts_post' => 'Stránka príspevku',
'posts_post_description' => 'Názov stránky príspevku kam budú smerovať odkazy "Zistiť viac". Táto hodnota je použitá v predvolenej čiastočnej stránke komponentu.',
'posts_except_post' => 'Okrem príspevku',
'posts_except_post_description' => 'Zadajte ID/URL alebo premennú s ID/URL príspevku, ktorý chcete vylúčiť',
'posts_except_categories' => 'Okrem kategórií',
'posts_except_categories_description' => 'Zadajte zoznam kategórií oddelený čiarkami alebo premennú s týmto zoznamom, ktoré chcete vylúčiť',
'rssfeed_blog' => 'Stránka blogu',
'rssfeed_blog_description' => 'Názov hlavnej stránky blogu na generovanie odkazov. Táto hodnota je použitá v predvolenej čiastočnej stránke komponentu.',
'rssfeed_title' => 'RSS Kanál',
'rssfeed_description' => 'Vygeneruje RSS kanál, ktorý obsahuje blogové príspevky.',
'group_links' => 'Odkazy',
'group_exceptions' => 'Výnimky'
],
'sorting' => [
'title_asc' => 'Názov (vzostupne)',
'title_desc' => 'Názov (zostupne)',
'created_asc' => 'Vytvorené (vzostupne)',
'created_desc' => 'Vytvorené (zostupne)',
'updated_asc' => 'Upravené (vzostupne)',
'updated_desc' => 'Upravené (zostupne)',
'published_asc' => 'Publikované (vzostupne)',
'published_desc' => 'Publikované (zostupne)',
'random' => 'Náhodne'
],
'import' => [
'update_existing_label' => 'Aktualizovať existujúce príspevky',
'update_existing_comment' => 'Začiarknutím tohto políčka aktualizujte príspevky, ktoré majú presne to isté ID, titul alebo URL príspevku.',
'auto_create_categories_label' => 'Vytvoriť kategórie zadané v importovanom súbore',
'auto_create_categories_comment' => 'Ak chcete túto funkciu použiť, mali by sa zhodovať so stĺpcom Kategórie, inak vyberte predvolené kategórie, ktoré chcete použiť z nižšie uvedených položiek.',
'categories_label' => 'Kategórie',
'categories_comment' => 'Vyberte kategórie, do ktorých budú patriť importované príspevky (voliteľné).',
'default_author_label' => 'Predvolený autor príspevku (voliteľné)',
'default_author_comment' => 'Import sa pokúsi použiť existujúceho autora, ak sa zhoduje so stĺpcom e-mail, inak sa použije vyššie uvedený autor.',
'default_author_placeholder' => '-- vyberte autora --'
]
];

View File

@ -0,0 +1,163 @@
<?php
return [
'plugin' => [
'name' => 'Blog',
'description' => 'Robustna platforma za bloganje.',
],
'blog' => [
'menu_label' => 'Blog',
'menu_description' => 'Upravljanje bloga',
'posts' => 'Objave',
'create_post' => 'Blog objava',
'categories' => 'Kategorije',
'create_category' => 'Blog kategorija',
'tab' => 'Blog',
'access_posts' => 'Upravljanje blog objav',
'access_categories' => 'Upravljanje blog kategorij',
'access_other_posts' => 'Upravljanje objav drugih uporabnikov',
'access_import_export' => 'Dovoljenje za uvoz in izvoz objav',
'access_publish' => 'Dovoljenje za objavljanje objav',
'manage_settings' => 'Urejanje nastavitev bloga',
'delete_confirm' => 'Ali ste prepričani?',
'chart_published' => 'Objavljeno',
'chart_drafts' => 'Osnutki',
'chart_total' => 'Skupaj',
'settings_description' => 'Urejanje nastavitev bloga',
'show_all_posts_label' => 'Administratorjem prikaži vse objave',
'show_all_posts_comment' => 'Na spletni strani prikaži administratorjem vse objavljene in neobjavljene objave.',
'tab_general' => 'Splošno',
],
'posts' => [
'list_title' => 'Urejanje blog objav',
'filter_category' => 'Kategorija',
'filter_published' => 'Objavljeno',
'filter_date' => 'Datum',
'new_post' => 'Nova objava',
'export_post' => 'Izvoz objav',
'import_post' => 'Uvoz objav',
],
'post' => [
'title' => 'Naslov',
'title_placeholder' => 'Naslov nove objave',
'content' => 'Vsebina',
'content_html' => 'HTML vsebina',
'slug' => 'Povezava',
'slug_placeholder' => 'povezava-nove-objave',
'categories' => 'Kategorije',
'author_email' => 'E-pošta avtorja',
'created' => 'Ustvarjeno',
'created_date' => 'Ustvarjeno dne',
'updated' => 'Posodobljeno',
'updated_date' => 'Posodobljeno dne',
'published' => 'Objavljeno',
'published_by' => 'Objavil',
'current_user' => 'Trenutni uporabnik',
'published_date' => 'Datum objave',
'published_validation' => 'Prosimo, podajte datum objave',
'tab_edit' => 'Upravljanje',
'tab_categories' => 'Kategorije',
'categories_comment' => 'Izberite kategorije, v katere spada objava',
'categories_placeholder' => 'Ni najdenih kategorij, ustvarite vsaj eno kategorijo!',
'tab_manage' => 'Urejanje',
'published_on' => 'Datum objave',
'excerpt' => 'Izvleček',
'summary' => 'Povzetek',
'featured_images' => 'Uporabljene slike',
'delete_confirm' => 'Želite izbrisati to objavo?',
'delete_success' => 'Te objave so bile uspešno izbrisane.',
'close_confirm' => 'Ta objava ni shranjena.',
'return_to_posts' => 'Vrnite se na seznam objav',
],
'categories' => [
'list_title' => 'Upravljanje blog kategorij',
'new_category' => 'Nova kategorija',
'uncategorized' => 'Nekategorizirano',
],
'category' => [
'name' => 'Naslov',
'name_placeholder' => 'Naslov nove kategorije',
'description' => 'Opis',
'slug' => 'Povezava',
'slug_placeholder' => 'povezava-nove-kategorije',
'posts' => 'Objave',
'delete_confirm' => 'Želite izbrisati to kategorijo?',
'delete_success' => 'Te kategorije so bile uspešno izbrisane.',
'return_to_categories' => 'Vrnite se na seznam blog kategorij',
'reorder' => 'Spremenite vrstni red kategorij',
],
'menuitem' => [
'blog_category' => 'Blog kategorija',
'all_blog_categories' => 'Vse blog kategorije',
'blog_post' => 'Blog objava',
'all_blog_posts' => 'Vse blog objave',
'category_blog_posts' => 'Objave v kategoriji',
],
'settings' => [
'category_title' => 'Seznam kategorij',
'category_description' => 'Prikaži seznam blog kategorij na strani.',
'category_slug' => 'Povezava kategorije',
'category_slug_description' => 'Omogoča pregled blog kategorije na podani povezavi. Ta lastnost je uporabljena v privzeti predlogi komponente za označevanje trenutno aktivne kategorije.',
'category_display_empty' => 'Prikaži prazne kategorije',
'category_display_empty_description' => 'Prikaže kategorije brez objav.',
'category_page' => 'Stran s kategorijo',
'category_page_description' => 'Naslov strani blog kategorij za ustvarjanje povezav. Ta lastnost je uporabljena v privzeti predlogi komponente.',
'post_title' => 'Objava',
'post_description' => 'Prikaži blog objavo na strani.',
'post_slug' => 'Povezava objave',
'post_slug_description' => "Omogoča pregled blog objave na podani povezavi.",
'post_category' => 'Stran s kategorijo',
'post_category_description' => 'Naslov strani blog kategorije za ustvarjanje povezav. Ta lastnost je uporabljena v privzeti predlogi komponente.',
'posts_title' => 'Seznam objav',
'posts_description' => 'Prikaži seznam najnovejših blog objav na strani.',
'posts_pagination' => 'Številka strani',
'posts_pagination_description' => 'Ta vrednost se uporablja za določitev, na kateri strani se nahaja uporabnik.',
'posts_filter' => 'Filter kategorij',
'posts_filter_description' => 'Vnesite povezavo kategorije ali URL parameter za filtriranje objav. Pustite prazno za prikaz vseh objav.',
'posts_per_page' => 'Število objav na strani',
'posts_per_page_validation' => 'Neveljaven format števila objav na strani',
'posts_no_posts' => 'Sporočilo brez objav',
'posts_no_posts_description' => 'Sporočilo, ki se prikaže na seznamu blog objav, če ni nobenih objav. Ta lastnost je uporabljena v privzeti predlogi komponente.',
'posts_no_posts_default' => 'Ni najdenih objav',
'posts_order' => 'Vrstni red objav',
'posts_order_description' => 'Lastnost, glede na katero naj bodo razvrščene objave',
'posts_category' => 'Stran s kategorijo',
'posts_category_description' => 'Naslov strani blog kategorije za povezave "Objavljeno v". Ta lastnost je uporabljena v privzeti predlogi komponente.',
'posts_post' => 'Stran z objavo',
'posts_post_description' => 'Naslov strani blog objave za povezave "Preberi več". Ta lastnost je uporabljena v privzeti predlogi komponente.',
'posts_except_post' => 'Izvzete objave',
'posts_except_post_description' => 'Vnesite ID/URL objave ali spremenljivko z ID-jem/URL-jem objave, ki jo želite izvzeti. Za določitev večjega števila objav lahko uporabite seznam, ločen z vejicami.',
'posts_except_post_validation' => 'Izvzete objave morajo biti posamezna povezava ali ID objave ali pa seznam povezav oz. ID-jev objav, ločen z vejicami.',
'posts_except_categories' => 'Izvzete kategorije',
'posts_except_categories_description' => 'Vnesite seznam povezav kategorij, ločen z vejicami ali pa spremenljivko, ki vključuje takšen seznam kategorij, ki jih želite izvzeti.',
'posts_except_categories_validation' => 'Izvzete kategorije morajo biti posamezna povezava kategorije ali pa seznam povezav kategorij, ločen z vejicami.',
'rssfeed_blog' => 'Stran z blogom',
'rssfeed_blog_description' => 'Naslov glavne strani bloga za ustvarjanje povezav. Ta lastnost je uporabljena v privzeti predlogi komponente.',
'rssfeed_title' => 'RSS vir',
'rssfeed_description' => 'Ustvari vir RSS, ki vsebuje objave iz bloga.',
'group_links' => 'Povezave',
'group_exceptions' => 'Izjeme',
],
'sorting' => [
'title_asc' => 'Naslov (naraščajoče)',
'title_desc' => 'Naslov (padajoče)',
'created_asc' => 'Ustvarjeno (naraščajoče)',
'created_desc' => 'Ustvarjeno (padajoče)',
'updated_asc' => 'Posodobljeno (naraščajoče)',
'updated_desc' => 'Posodobljeno (padajoče)',
'published_asc' => 'Objavljeno (naraščajoče)',
'published_desc' => 'Objavljeno (padajoče)',
'random' => 'Naključno',
],
'import' => [
'update_existing_label' => 'Posodobi obstoječe objave',
'update_existing_comment' => 'Označite kvadratek, če želite posodobiti objave, ki imajo popolnoma enak ID, naslov ali povezavo.',
'auto_create_categories_label' => 'Ustvari kategorije, določene v uvozni datoteki',
'auto_create_categories_comment' => "Za uporabo te možnosti morate ali povezati stolpec 'Kategorije' ali pa označiti privzete kategorije za uporabo iz spodnjega seznama.",
'categories_label' => 'Kategorije',
'categories_comment' => 'Izberite kategorije, na katere bodo povezavne uvožene objave (neobvezno).',
'default_author_label' => 'Privzeti avtor objave (neobvezno)',
'default_author_comment' => "Uvoz bo poskusil uporabiti obstoječega avtorja, če povežete stolpec 'E-pošta avtorja', sicer se bo uporabil zgoraj navedeni avtor.",
'default_author_placeholder' => '-- izberite avtorja --',
],
];

View File

@ -0,0 +1,161 @@
<?php
return [
'plugin' => [
'name' => 'Blog',
'description' => 'Sağlam blog platformu.',
],
'blog' => [
'menu_label' => 'Blog',
'menu_description' => 'Blog Gönderilerini Yönet',
'posts' => 'Gönderiler',
'create_post' => 'Blog gönderisi',
'categories' => 'Kategoriler',
'create_category' => 'Blog kategorisi',
'tab' => 'Blog',
'access_posts' => 'Gönderileri yönetebilsin',
'access_categories' => 'Blog kategorilerini yönetebilsin',
'access_other_posts' => 'Diğer kullanıcıların gönderilerini yönetebilsin',
'access_import_export' => 'Gönderileri içeri/dışarı aktarabilsin',
'access_publish' => 'Gönderi yayınlayabilsin',
'manage_settings' => 'Blog ayarlarını yönet',
'delete_confirm' => 'Emin misiniz?',
'chart_published' => 'Yayınlandı',
'chart_drafts' => 'Taslaklar',
'chart_total' => 'Toplam',
'settings_description' => 'Blog ayarlarını yönet',
'show_all_posts_label' => 'Tüm gönderileri yönetim paneli kullanıcılarına göster',
'show_all_posts_comment' => 'Hem yayınlanmış hem de yayınlanmamış gönderileri önyüzde yönetim paneli kullanıcılarına göster.',
'tab_general' => 'Genel',
],
'posts' => [
'list_title' => 'Blog gönderilerini yönet',
'filter_category' => 'Kategori',
'filter_published' => 'Yayınlanan',
'filter_date' => 'Tarih',
'new_post' => 'Yeni gönderi',
'export_post' => 'Gönderileri dışarı aktar',
'import_post' => 'Gönderileri içeri aktar',
],
'post' => [
'title' => 'Başlık',
'title_placeholder' => 'Yeni gönderi başlığı',
'content' => 'İçerik',
'content_html' => 'HTML İçeriği',
'slug' => 'Kısa URL',
'slug_placeholder' => 'yeni-gonderi-basligi',
'categories' => 'Kategoriler',
'author_email' => 'Yazar E-mail',
'created' => 'Oluşturuldu',
'created_date' => 'Oluşturulma tarihi',
'updated' => 'Güncellendi',
'updated_date' => 'Güncellenme tarihi',
'published' => 'Yayınlandı',
'published_date' => 'Yayınlanma tarihi',
'published_validation' => 'Lütfen yayınlama tarihini belirtiniz',
'tab_edit' => 'Düzenle',
'tab_categories' => 'Kategoriler',
'categories_comment' => 'Gönderinin ait olduğu kategorileri seçiniz',
'categories_placeholder' => 'Kategori yok, öncelikle bir kategori oluşturmalısınız!',
'tab_manage' => 'Yönet',
'published_on' => 'Yayınlandı',
'excerpt' => 'Alıntı',
'summary' => 'Özet',
'featured_images' => 'Öne Çıkan Görseller',
'delete_confirm' => 'Bu yazıyı silmek istiyor musunuz?',
'delete_success' => 'Gönderi(ler) silindi.',
'close_confirm' => 'Gönderi kaydedilmedi.',
'return_to_posts' => 'Gönderi listesine dön',
],
'categories' => [
'list_title' => 'Blog kategorilerini yönet',
'new_category' => 'Yeni kategori',
'uncategorized' => 'Kategorisiz',
],
'category' => [
'name' => 'İsim',
'name_placeholder' => 'Yeni kategori adı',
'description' => 'Açıklama',
'slug' => 'Kısa URL',
'slug_placeholder' => 'yeni-kategori-basligi',
'posts' => 'Gönderiler',
'delete_confirm' => 'Bu kategoriyi silmek istiyor musunuz?',
'delete_success' => 'Kategori(ler) silindi.',
'return_to_categories' => 'Kategori listesine dön',
'reorder' => 'Kategorileri yeniden sırala',
],
'menuitem' => [
'blog_category' => 'Blog kategorisi',
'all_blog_categories' => 'Tüm blog kategorileri',
'blog_post' => 'Blog gönderisi',
'all_blog_posts' => 'Tüm blog gönderileri',
'category_blog_posts' => 'Blog kategori gönderileri',
],
'settings' => [
'category_title' => 'Kategori Listesi',
'category_description' => 'Kategorilerin listesini sayfada göster.',
'category_slug' => 'Kategori Kısa URL',
'category_slug_description' => 'Verilen kısa URLi kullanarak blog kategorisini görüntüle. Bu özellik şu anki aktif kategoriyi işaretlemek için varsayılan kısmi bileşeni tarafından kullanılır',
'category_display_empty' => 'Boş kategorileri göster',
'category_display_empty_description' => 'Herhangi bir gönderi olmayan kategorileri göster.',
'category_page' => 'Kategori sayfası',
'category_page_description' => 'Kategori bağlantıları için kategori sayfası dosyasının adı. Bu özellik varsayılan kısmi bileşeni tarafından kullanılır.',
'post_title' => 'Gönderi',
'post_description' => 'Sayfada bir blog gönderisi gösterir.',
'post_slug' => 'Gönderi Kısa URL',
'post_slug_description' => 'Verilen kısa URL ile blog gönderisine bakın.',
'post_category' => 'Kategori sayfası',
'post_category_description' => 'Kategori bağlantıları için kategori sayfası dosyasının adı. Bu özellik varsayılan kısmi bileşeni tarafından kullanılır.',
'posts_title' => 'Gönderi listesi',
'posts_description' => 'Sayfada son blog gönderilerinin listesini gösterir.',
'posts_pagination' => 'Sayfa numarası',
'posts_pagination_description' => 'Bu değer kullanıcının hangi sayfada olduğunu belirlemek için kullanılır.',
'posts_filter' => 'Kategori filtresi',
'posts_filter_description' => 'Gönderileri filtrelemek için kategori kısa URLsi ya da URL parametresi girin. Tüm gönderiler için boş bırakın.',
'posts_per_page' => 'Sayfa başına gönderi',
'posts_per_page_validation' => 'Sayfa başına gönderi için geçersiz format',
'posts_no_posts' => 'Gönderi mesajı yok',
'posts_no_posts_description' => 'Eğer bir gönderi yoksa gönderi listesinde görüntülenecek mesaj. Bu özellik varsayılan kısmi bileşeni tarafından kullanılır.',
'posts_no_posts_default' => 'Gönderi yok',
'posts_order' => 'Gönderi Sırası',
'posts_order_description' => 'Gönderilerin sıralama türü',
'posts_category' => 'Kategori sayfası',
'posts_category_description' => '"Yayınlanan" kategori bağlantıları için kategori sayfası dosyasının adı. Bu özellik varsayılan kısmi bileşeni tarafından kullanılır.',
'posts_post' => 'Gönderi sayfası',
'posts_post_description' => '"Daha fazla bilgi edinin" bağlantıları için gönderi sayfası dosyasının adı. Bu özellik varsayılan kısmi bileşeni tarafından kullanılır.',
'posts_except_post' => 'Hariç tutulacak gönderi',
'posts_except_post_description' => 'Hariç tutmak istediğiniz gönderinin ID/URL ini veya ID/URL içeren bir değişken girin. Birden çok gönderi belirtmek için virgülle ayrılmış liste kullanabilirsiniz.',
'posts_except_post_validation' => 'Hariç tutulacak gönderi değeri tek bir kısa URL veya ID, veya virgülle ayrılmış kısa URL veya ID listesi olmalıdır.',
'posts_except_categories' => 'Hariç tutulacak kategoriler',
'posts_except_categories_description' => 'Hariç tutmak istediğiniz kategori listesini içeren virgülle ayrılmış bir kategori listesi veya listeyi içeren bir değişken girin.',
'posts_except_categories_validation' => 'Hariç tutulacak kategoriler değeri tek bir kısa URL, veya virgülle ayrılmış kısa URL listesi olmalıdır.',
'rssfeed_blog' => 'Blog sayfası',
'rssfeed_blog_description' => 'Linkleri üretmek için ana blog sayfasının adı. Bu özellik, varsayılan kısmi bileşeni tarafından kullanılır.',
'rssfeed_title' => 'RSS Beslemesi',
'rssfeed_description' => 'Blog içerisindeki gönderileri veren RSS beslemesi oluşturur.',
'group_links' => 'Linkler',
'group_exceptions' => 'Hariç olanlar',
],
'sorting' => [
'title_asc' => 'Başlık (a-z)',
'title_desc' => 'Başlık (z-a)',
'created_asc' => 'Oluşturulma (yeniden eskiye)',
'created_desc' => 'Oluşturulma (eskiden yeniye)',
'updated_asc' => 'Güncellenme (yeniden eskiye)',
'updated_desc' => 'Güncellenme (eskiden yeniye)',
'published_asc' => 'Yayınlanma (yeniden eskiye)',
'published_desc' => 'Yayınlanma (eskiden yeniye)',
'random' => 'Rastgele',
],
'import' => [
'update_existing_label' => 'Mevcut gönderileri güncelle',
'update_existing_comment' => 'Tam olarak aynı ID, başlık veya kısa URL içeren gönderileri güncellemek için bu kutuyu işaretleyin.',
'auto_create_categories_label' => 'İçe aktarma dosyasında bulunan kategorileri oluştur',
'auto_create_categories_comment' => 'Bu özelliği kullanmak için Kategoriler sütununu eşleştirmelisiniz, aksi takdirde aşağıdaki öğelerden kullanılacak varsayılan kategorileri seçmelisiniz.',
'categories_label' => 'Kategoriler',
'categories_comment' => 'İçe aktarılan gönderilerin ait olacağı kategorileri seçin (isteğe bağlı).',
'default_author_label' => 'Varsayılan gönderi yazarı (isteğe bağlı)',
'default_author_comment' => 'İçe aktarma, Yazar E-postası sütunuyla eşleşirse mevcut bir yazarı gönderi için kullanmaya çalışır, aksi takdirde yukarıda belirtilen yazar seçilir.',
'default_author_placeholder' => '-- yazar seçin --',
],
];

View File

@ -0,0 +1,124 @@
<?php
return [
'plugin' => [
'name' => '博客',
'description' => '一个强大的博客平台.'
],
'blog' => [
'menu_label' => '博客',
'menu_description' => '管理博客帖子',
'posts' => '帖子',
'create_post' => '博客帖子',
'categories' => '分类',
'create_category' => '博客分类',
'tab' => '博客',
'access_posts' => '管理博客帖子',
'access_categories' => '管理博客分类',
'access_other_posts' => '管理其他用户帖子',
'access_import_export' => '允许导入和导出',
'access_publish' => '允许发布帖子',
'delete_confirm' => '你确定?',
'chart_published' => '已发布',
'chart_drafts' => '草稿',
'chart_total' => '总数'
],
'posts' => [
'list_title' => '管理博客帖子',
'filter_category' => '分类',
'filter_published' => '发布',
'filter_date' => '日期',
'new_post' => '创建帖子',
'export_post' => '导出帖子',
'import_post' => '导入帖子'
],
'post' => [
'title' => '标题',
'title_placeholder' => '新帖子标题',
'content' => '内容',
'content_html' => 'HTML 内容',
'slug' => '别名',
'slug_placeholder' => 'new-post-slug',
'categories' => '分类',
'author_email' => '作者邮箱',
'created' => '创建时间',
'created_date' => '创建日期',
'updated' => '更新时间',
'updated_date' => '更新日期',
'published' => '发布时间',
'published_date' => '发布日期',
'published_validation' => '请指定发布日期',
'tab_edit' => '编辑',
'tab_categories' => '分类',
'categories_comment' => '选择帖子属于那个分类',
'categories_placeholder' => '没有分类,你应该先创建一个分类!',
'tab_manage' => '管理',
'published_on' => '发布于',
'excerpt' => '摘录',
'summary' => '总结',
'featured_images' => '特色图片',
'delete_confirm' => '确定删除该帖子?',
'close_confirm' => '该帖子未保存.',
'return_to_posts' => '返回帖子列表'
],
'categories' => [
'list_title' => '管理博客分类',
'new_category' => '新分类',
'uncategorized' => '未分类'
],
'category' => [
'name' => '名称',
'name_placeholder' => '新分类名称',
'description' => '描述',
'slug' => '别名',
'slug_placeholder' => 'new-category-slug',
'posts' => '帖子',
'delete_confirm' => '确定删除分类?',
'return_to_categories' => '返回博客分类列表',
'reorder' => '重新排序分类'
],
'menuitem' => [
'blog_category' => '博客分类',
'all_blog_categories' => '所有博客分类',
'blog_post' => '博客帖子',
'all_blog_posts' => '所有博客帖子'
],
'settings' => [
'category_title' => '分类列表',
'category_description' => '在页面上显示帖子分类列表.',
'category_slug' => '分类别名',
'category_slug_description' => "用分类别名查找博客分类. 该值被默认组件的partial用来激活当前分类.",
'category_display_empty' => '显示空的分类',
'category_display_empty_description' => '显示没有帖子的分类.',
'category_page' => '分类页',
'category_page_description' => '用来生成分类链接的分类页面文件名称. 该属性被默认组件partial所使用.',
'post_title' => '帖子',
'post_description' => '在页面上显示博客帖子.',
'post_slug' => '帖子别名',
'post_slug_description' => "用帖子别名查找博客帖子.",
'post_category' => '分类页',
'post_category_description' => '用来生成分类链接的分类页面文件名称. 该属性被默认组件partial所使用.',
'posts_title' => '帖子列表',
'posts_description' => '在页面上显示最近发布的博客帖子列表.',
'posts_pagination' => '页数',
'posts_pagination_description' => '该值用来判定用户所在页面.',
'posts_filter' => '过滤分类',
'posts_filter_description' => '输入分类的别名(slug)或者URL参数来过滤帖子. 留空显示所有帖子.',
'posts_per_page' => '每页帖子数',
'posts_per_page_validation' => '每一页帖子数量的值的格式错误',
'posts_no_posts' => '没有帖子的消息',
'posts_no_posts_description' => '如果博客帖子列表中一个帖子都没有要显示的提示消息. 该属性被默认组件partial所使用.',
'posts_order' => '帖子排序',
'posts_order_description' => '帖子排序的属性',
'posts_category' => '分类页',
'posts_category_description' => '用来生成"发布到"分类链接的分类页文件名称. 该属性被默认组件partial所使用.',
'posts_post' => '帖子页',
'posts_post_description' => ' 查看帖子的"详情"的页面文件. 该属性被默认组件partial所使用.',
'posts_except_post' => '排除的帖子',
'posts_except_post_description' => '输入帖子的ID/URL或者变量来排除你不想看见的帖子',
'rssfeed_blog' => '博客页面',
'rssfeed_blog_description' => '生成博客帖子首页面文件名称. 该属性被默认组件partial所使用.',
'rssfeed_title' => 'RSS Feed',
'rssfeed_description' => '从博客生成一个包含帖子的RSS Feed.'
]
];

View File

@ -0,0 +1,315 @@
<?php namespace RainLab\Blog\Models;
use Str;
use Model;
use Url;
use Cms\Classes\Page as CmsPage;
use Cms\Classes\Theme;
class Category extends Model
{
use \October\Rain\Database\Traits\Validation;
use \October\Rain\Database\Traits\NestedTree;
public $table = 'rainlab_blog_categories';
public $implement = ['@RainLab.Translate.Behaviors.TranslatableModel'];
/*
* Validation
*/
public $rules = [
'name' => 'required',
'slug' => 'required|between:3,64|unique:rainlab_blog_categories',
'code' => 'nullable|unique:rainlab_blog_categories',
];
/**
* @var array Attributes that support translation, if available.
*/
public $translatable = [
'name',
'description',
['slug', 'index' => true]
];
protected $guarded = [];
public $belongsToMany = [
'posts' => ['RainLab\Blog\Models\Post',
'table' => 'rainlab_blog_posts_categories',
'order' => 'published_at desc',
'scope' => 'isPublished'
],
'posts_count' => ['RainLab\Blog\Models\Post',
'table' => 'rainlab_blog_posts_categories',
'scope' => 'isPublished',
'count' => true
]
];
public function beforeValidate()
{
// Generate a URL slug for this model
if (!$this->exists && !$this->slug) {
$this->slug = Str::slug($this->name);
}
}
public function afterDelete()
{
$this->posts()->detach();
}
public function getPostCountAttribute()
{
return optional($this->posts_count->first())->count ?? 0;
}
/**
* Count posts in this and nested categories
* @return int
*/
public function getNestedPostCount()
{
return $this->post_count + $this->children->sum(function ($category) {
return $category->getNestedPostCount();
});
}
/**
* Sets the "url" attribute with a URL to this object
*
* @param string $pageName
* @param Cms\Classes\Controller $controller
*
* @return string
*/
public function setUrl($pageName, $controller)
{
$params = [
'id' => $this->id,
'slug' => $this->slug
];
return $this->url = $controller->pageUrl($pageName, $params, false);
}
/**
* Handler for the pages.menuitem.getTypeInfo event.
* Returns a menu item type information. The type information is returned as array
* with the following elements:
* - references - a list of the item type reference options. The options are returned in the
* ["key"] => "title" format for options that don't have sub-options, and in the format
* ["key"] => ["title"=>"Option title", "items"=>[...]] for options that have sub-options. Optional,
* required only if the menu item type requires references.
* - nesting - Boolean value indicating whether the item type supports nested items. Optional,
* false if omitted.
* - dynamicItems - Boolean value indicating whether the item type could generate new menu items.
* Optional, false if omitted.
* - cmsPages - a list of CMS pages (objects of the Cms\Classes\Page class), if the item type requires a CMS page reference to
* resolve the item URL.
* @param string $type Specifies the menu item type
* @return array Returns an array
*/
public static function getMenuTypeInfo($type)
{
$result = [];
if ($type == 'blog-category') {
$result = [
'references' => self::listSubCategoryOptions(),
'nesting' => true,
'dynamicItems' => true
];
}
if ($type == 'all-blog-categories') {
$result = [
'dynamicItems' => true
];
}
if ($result) {
$theme = Theme::getActiveTheme();
$pages = CmsPage::listInTheme($theme, true);
$cmsPages = [];
foreach ($pages as $page) {
if (!$page->hasComponent('blogPosts')) {
continue;
}
/*
* Component must use a category filter with a routing parameter
* eg: categoryFilter = "{{ :somevalue }}"
*/
$properties = $page->getComponentProperties('blogPosts');
if (!isset($properties['categoryFilter']) || !preg_match('/{{\s*:/', $properties['categoryFilter'])) {
continue;
}
$cmsPages[] = $page;
}
$result['cmsPages'] = $cmsPages;
}
return $result;
}
protected static function listSubCategoryOptions()
{
$category = self::getNested();
$iterator = function($categories) use (&$iterator) {
$result = [];
foreach ($categories as $category) {
if (!$category->children) {
$result[$category->id] = $category->name;
}
else {
$result[$category->id] = [
'title' => $category->name,
'items' => $iterator($category->children)
];
}
}
return $result;
};
return $iterator($category);
}
/**
* Handler for the pages.menuitem.resolveItem event.
* Returns information about a menu item. The result is an array
* with the following keys:
* - url - the menu item URL. Not required for menu item types that return all available records.
* The URL should be returned relative to the website root and include the subdirectory, if any.
* Use the Url::to() helper to generate the URLs.
* - isActive - determines whether the menu item is active. Not required for menu item types that
* return all available records.
* - items - an array of arrays with the same keys (url, isActive, items) + the title key.
* The items array should be added only if the $item's $nesting property value is TRUE.
* @param \RainLab\Pages\Classes\MenuItem $item Specifies the menu item.
* @param \Cms\Classes\Theme $theme Specifies the current theme.
* @param string $url Specifies the current page URL, normalized, in lower case
* The URL is specified relative to the website root, it includes the subdirectory name, if any.
* @return mixed Returns an array. Returns null if the item cannot be resolved.
*/
public static function resolveMenuItem($item, $url, $theme)
{
$result = null;
if ($item->type == 'blog-category') {
if (!$item->reference || !$item->cmsPage) {
return;
}
$category = self::find($item->reference);
if (!$category) {
return;
}
$pageUrl = self::getCategoryPageUrl($item->cmsPage, $category, $theme);
if (!$pageUrl) {
return;
}
$pageUrl = Url::to($pageUrl);
$result = [];
$result['url'] = $pageUrl;
$result['isActive'] = $pageUrl == $url;
$result['mtime'] = $category->updated_at;
if ($item->nesting) {
$iterator = function($categories) use (&$iterator, &$item, &$theme, $url) {
$branch = [];
foreach ($categories as $category) {
$branchItem = [];
$branchItem['url'] = self::getCategoryPageUrl($item->cmsPage, $category, $theme);
$branchItem['isActive'] = $branchItem['url'] == $url;
$branchItem['title'] = $category->name;
$branchItem['mtime'] = $category->updated_at;
if ($category->children) {
$branchItem['items'] = $iterator($category->children);
}
$branch[] = $branchItem;
}
return $branch;
};
$result['items'] = $iterator($category->children);
}
}
elseif ($item->type == 'all-blog-categories') {
$result = [
'items' => []
];
$categories = self::with('posts_count')->orderBy('name')->get();
foreach ($categories as $category) {
try {
$postCount = $category->posts_count->first()->count ?? null;
if ($postCount === 0) {
continue;
}
}
catch (\Exception $ex) {}
$categoryItem = [
'title' => $category->name,
'url' => self::getCategoryPageUrl($item->cmsPage, $category, $theme),
'mtime' => $category->updated_at
];
$categoryItem['isActive'] = $categoryItem['url'] == $url;
$result['items'][] = $categoryItem;
}
}
return $result;
}
/**
* Returns URL of a category page.
*
* @param $pageCode
* @param $category
* @param $theme
*/
protected static function getCategoryPageUrl($pageCode, $category, $theme)
{
$page = CmsPage::loadCached($theme, $pageCode);
if (!$page) {
return;
}
$properties = $page->getComponentProperties('blogPosts');
if (!isset($properties['categoryFilter'])) {
return;
}
/*
* Extract the routing parameter name from the category filter
* eg: {{ :someRouteParam }}
*/
if (!preg_match('/^\{\{([^\}]+)\}\}$/', $properties['categoryFilter'], $matches)) {
return;
}
$paramName = substr(trim($matches[1]), 1);
$url = CmsPage::url($page->getBaseFileName(), [$paramName => $category->slug]);
return $url;
}
}

View File

@ -0,0 +1,708 @@
<?php namespace RainLab\Blog\Models;
use Url;
use Html;
use Lang;
use Model;
use Config;
use Markdown;
use BackendAuth;
use Carbon\Carbon;
use Backend\Models\User as BackendUser;
use Cms\Classes\Page as CmsPage;
use Cms\Classes\Theme;
use Cms\Classes\Controller;
use October\Rain\Database\NestedTreeScope;
use RainLab\Blog\Classes\TagProcessor;
use ValidationException;
/**
* Class Post
*/
class Post extends Model
{
use \October\Rain\Database\Traits\Validation;
public $table = 'rainlab_blog_posts';
public $implement = ['@RainLab.Translate.Behaviors.TranslatableModel'];
/*
* Validation
*/
public $rules = [
'title' => 'required',
'slug' => ['required', 'regex:/^[a-z0-9\/\:_\-\*\[\]\+\?\|]*$/i', 'unique:rainlab_blog_posts'],
'content' => 'required',
'excerpt' => ''
];
/**
* @var array Attributes that support translation, if available.
*/
public $translatable = [
'title',
'content',
'content_html',
'excerpt',
'metadata',
['slug', 'index' => true]
];
/**
* @var array Attributes to be stored as JSON
*/
protected $jsonable = ['metadata'];
/**
* The attributes that should be mutated to dates.
* @var array
*/
protected $dates = ['published_at'];
/**
* The attributes on which the post list can be ordered.
* @var array
*/
public static $allowedSortingOptions = [
'title asc' => 'rainlab.blog::lang.sorting.title_asc',
'title desc' => 'rainlab.blog::lang.sorting.title_desc',
'created_at asc' => 'rainlab.blog::lang.sorting.created_asc',
'created_at desc' => 'rainlab.blog::lang.sorting.created_desc',
'updated_at asc' => 'rainlab.blog::lang.sorting.updated_asc',
'updated_at desc' => 'rainlab.blog::lang.sorting.updated_desc',
'published_at asc' => 'rainlab.blog::lang.sorting.published_asc',
'published_at desc' => 'rainlab.blog::lang.sorting.published_desc',
'random' => 'rainlab.blog::lang.sorting.random'
];
/*
* Relations
*/
public $belongsTo = [
'user' => BackendUser::class
];
public $belongsToMany = [
'categories' => [
Category::class,
'table' => 'rainlab_blog_posts_categories',
'order' => 'name'
]
];
public $attachMany = [
'featured_images' => [\System\Models\File::class, 'order' => 'sort_order'],
'content_images' => \System\Models\File::class
];
/**
* @var array The accessors to append to the model's array form.
*/
protected $appends = ['summary', 'has_summary'];
public $preview = null;
/**
* Limit visibility of the published-button
*
* @param $fields
* @param null $context
* @return void
*/
public function filterFields($fields, $context = null)
{
if (!isset($fields->published, $fields->published_at)) {
return;
}
$user = BackendAuth::getUser();
if (!$user->hasAnyAccess(['rainlab.blog.access_publish'])) {
$fields->published->hidden = true;
$fields->published_at->hidden = true;
}
else {
$fields->published->hidden = false;
$fields->published_at->hidden = false;
}
}
public function afterValidate()
{
if ($this->published && !$this->published_at) {
throw new ValidationException([
'published_at' => Lang::get('rainlab.blog::lang.post.published_validation')
]);
}
}
public function getUserOptions()
{
$options = [];
foreach (BackendUser::all() as $user) {
$options[$user->id] = $user->fullname . ' ('.$user->login.')';
}
return $options;
}
public function beforeSave()
{
if (empty($this->user)) {
$user = BackendAuth::getUser();
if (!is_null($user)) {
$this->user = $user->id;
}
}
$this->content_html = self::formatHtml($this->content);
}
/**
* Sets the "url" attribute with a URL to this object.
* @param string $pageName
* @param Controller $controller
* @param array $params Override request URL parameters
*
* @return string
*/
public function setUrl($pageName, $controller, $params = [])
{
$params = array_merge([
'id' => $this->id,
'slug' => $this->slug,
], $params);
if (empty($params['category'])) {
$params['category'] = $this->categories->count() ? $this->categories->first()->slug : null;
}
// Expose published year, month and day as URL parameters.
if ($this->published) {
$params['year'] = $this->published_at->format('Y');
$params['month'] = $this->published_at->format('m');
$params['day'] = $this->published_at->format('d');
}
return $this->url = $controller->pageUrl($pageName, $params);
}
/**
* Used to test if a certain user has permission to edit post,
* returns TRUE if the user is the owner or has other posts access.
* @param BackendUser $user
* @return bool
*/
public function canEdit(BackendUser $user)
{
return ($this->user_id == $user->id) || $user->hasAnyAccess(['rainlab.blog.access_other_posts']);
}
public static function formatHtml($input, $preview = false)
{
$result = Markdown::parse(trim($input));
// Check to see if the HTML should be cleaned from potential XSS
$user = BackendAuth::getUser();
if (!$user || !$user->hasAccess('backend.allow_unsafe_markdown')) {
$result = Html::clean($result);
}
if ($preview) {
$result = str_replace('<pre>', '<pre class="prettyprint">', $result);
}
$result = TagProcessor::instance()->processTags($result, $preview);
return $result;
}
//
// Scopes
//
public function scopeIsPublished($query)
{
return $query
->whereNotNull('published')
->where('published', true)
->whereNotNull('published_at')
->where('published_at', '<', Carbon::now())
;
}
/**
* Lists posts for the frontend
*
* @param $query
* @param array $options Display options
* @return Post
*/
public function scopeListFrontEnd($query, $options)
{
/*
* Default options
*/
extract(array_merge([
'page' => 1,
'perPage' => 30,
'sort' => 'created_at',
'categories' => null,
'exceptCategories' => null,
'category' => null,
'search' => '',
'published' => true,
'exceptPost' => null
], $options));
$searchableFields = ['title', 'slug', 'excerpt', 'content'];
if ($published) {
$query->isPublished();
}
/*
* Except post(s)
*/
if ($exceptPost) {
$exceptPosts = (is_array($exceptPost)) ? $exceptPost : [$exceptPost];
$exceptPostIds = [];
$exceptPostSlugs = [];
foreach ($exceptPosts as $exceptPost) {
$exceptPost = trim($exceptPost);
if (is_numeric($exceptPost)) {
$exceptPostIds[] = $exceptPost;
} else {
$exceptPostSlugs[] = $exceptPost;
}
}
if (count($exceptPostIds)) {
$query->whereNotIn('id', $exceptPostIds);
}
if (count($exceptPostSlugs)) {
$query->whereNotIn('slug', $exceptPostSlugs);
}
}
/*
* Sorting
*/
if (in_array($sort, array_keys(static::$allowedSortingOptions))) {
if ($sort == 'random') {
$query->inRandomOrder();
} else {
@list($sortField, $sortDirection) = explode(' ', $sort);
if (is_null($sortDirection)) {
$sortDirection = "desc";
}
$query->orderBy($sortField, $sortDirection);
}
}
/*
* Search
*/
$search = trim($search);
if (strlen($search)) {
$query->searchWhere($search, $searchableFields);
}
/*
* Categories
*/
if ($categories !== null) {
$categories = is_array($categories) ? $categories : [$categories];
$query->whereHas('categories', function($q) use ($categories) {
$q->withoutGlobalScope(NestedTreeScope::class)->whereIn('id', $categories);
});
}
/*
* Except Categories
*/
if (!empty($exceptCategories)) {
$exceptCategories = is_array($exceptCategories) ? $exceptCategories : [$exceptCategories];
array_walk($exceptCategories, 'trim');
$query->whereDoesntHave('categories', function ($q) use ($exceptCategories) {
$q->withoutGlobalScope(NestedTreeScope::class)->whereIn('slug', $exceptCategories);
});
}
/*
* Category, including children
*/
if ($category !== null) {
$category = Category::find($category);
$categories = $category->getAllChildrenAndSelf()->lists('id');
$query->whereHas('categories', function($q) use ($categories) {
$q->withoutGlobalScope(NestedTreeScope::class)->whereIn('id', $categories);
});
}
return $query->paginate($perPage, $page);
}
/**
* Allows filtering for specifc categories.
* @param Illuminate\Query\Builder $query QueryBuilder
* @param array $categories List of category ids
* @return Illuminate\Query\Builder QueryBuilder
*/
public function scopeFilterCategories($query, $categories)
{
return $query->whereHas('categories', function($q) use ($categories) {
$q->withoutGlobalScope(NestedTreeScope::class)->whereIn('id', $categories);
});
}
//
// Summary / Excerpt
//
/**
* Used by "has_summary", returns true if this post uses a summary (more tag).
* @return boolean
*/
public function getHasSummaryAttribute()
{
$more = Config::get('rainlab.blog::summary_separator', '<!-- more -->');
$length = Config::get('rainlab.blog::summary_default_length', 600);
return (
!!strlen(trim($this->excerpt)) ||
strpos($this->content_html, $more) !== false ||
strlen(Html::strip($this->content_html)) > $length
);
}
/**
* Used by "summary", if no excerpt is provided, generate one from the content.
* Returns the HTML content before the <!-- more --> tag or a limited 600
* character version.
*
* @return string
*/
public function getSummaryAttribute()
{
$excerpt = $this->excerpt;
if (strlen(trim($excerpt))) {
return $excerpt;
}
$more = Config::get('rainlab.blog::summary_separator', '<!-- more -->');
if (strpos($this->content_html, $more) !== false) {
$parts = explode($more, $this->content_html);
return array_get($parts, 0);
}
$length = Config::get('rainlab.blog::summary_default_length', 600);
return Html::limit($this->content_html, $length);
}
//
// Next / Previous
//
/**
* Apply a constraint to the query to find the nearest sibling
*
* // Get the next post
* Post::applySibling()->first();
*
* // Get the previous post
* Post::applySibling(-1)->first();
*
* // Get the previous post, ordered by the ID attribute instead
* Post::applySibling(['direction' => -1, 'attribute' => 'id'])->first();
*
* @param $query
* @param array $options
* @return
*/
public function scopeApplySibling($query, $options = [])
{
if (!is_array($options)) {
$options = ['direction' => $options];
}
extract(array_merge([
'direction' => 'next',
'attribute' => 'published_at'
], $options));
$isPrevious = in_array($direction, ['previous', -1]);
$directionOrder = $isPrevious ? 'asc' : 'desc';
$directionOperator = $isPrevious ? '>' : '<';
$query->where('id', '<>', $this->id);
if (!is_null($this->$attribute)) {
$query->where($attribute, $directionOperator, $this->$attribute);
}
return $query->orderBy($attribute, $directionOrder);
}
/**
* Returns the next post, if available.
* @return self
*/
public function nextPost()
{
return self::isPublished()->applySibling()->first();
}
/**
* Returns the previous post, if available.
* @return self
*/
public function previousPost()
{
return self::isPublished()->applySibling(-1)->first();
}
//
// Menu helpers
//
/**
* Handler for the pages.menuitem.getTypeInfo event.
* Returns a menu item type information. The type information is returned as array
* with the following elements:
* - references - a list of the item type reference options. The options are returned in the
* ["key"] => "title" format for options that don't have sub-options, and in the format
* ["key"] => ["title"=>"Option title", "items"=>[...]] for options that have sub-options. Optional,
* required only if the menu item type requires references.
* - nesting - Boolean value indicating whether the item type supports nested items. Optional,
* false if omitted.
* - dynamicItems - Boolean value indicating whether the item type could generate new menu items.
* Optional, false if omitted.
* - cmsPages - a list of CMS pages (objects of the Cms\Classes\Page class), if the item type requires a CMS page reference to
* resolve the item URL.
*
* @param string $type Specifies the menu item type
* @return array Returns an array
*/
public static function getMenuTypeInfo($type)
{
$result = [];
if ($type == 'blog-post') {
$references = [];
$posts = self::orderBy('title')->get();
foreach ($posts as $post) {
$references[$post->id] = $post->title;
}
$result = [
'references' => $references,
'nesting' => false,
'dynamicItems' => false
];
}
if ($type == 'all-blog-posts') {
$result = [
'dynamicItems' => true
];
}
if ($type == 'category-blog-posts') {
$references = [];
$categories = Category::orderBy('name')->get();
foreach ($categories as $category) {
$references[$category->id] = $category->name;
}
$result = [
'references' => $references,
'dynamicItems' => true
];
}
if ($result) {
$theme = Theme::getActiveTheme();
$pages = CmsPage::listInTheme($theme, true);
$cmsPages = [];
foreach ($pages as $page) {
if (!$page->hasComponent('blogPost')) {
continue;
}
/*
* Component must use a categoryPage filter with a routing parameter and post slug
* eg: categoryPage = "{{ :somevalue }}", slug = "{{ :somevalue }}"
*/
$properties = $page->getComponentProperties('blogPost');
if (!isset($properties['categoryPage']) || !preg_match('/{{\s*:/', $properties['slug'])) {
continue;
}
$cmsPages[] = $page;
}
$result['cmsPages'] = $cmsPages;
}
return $result;
}
/**
* Handler for the pages.menuitem.resolveItem event.
* Returns information about a menu item. The result is an array
* with the following keys:
* - url - the menu item URL. Not required for menu item types that return all available records.
* The URL should be returned relative to the website root and include the subdirectory, if any.
* Use the Url::to() helper to generate the URLs.
* - isActive - determines whether the menu item is active. Not required for menu item types that
* return all available records.
* - items - an array of arrays with the same keys (url, isActive, items) + the title key.
* The items array should be added only if the $item's $nesting property value is TRUE.
*
* @param \RainLab\Pages\Classes\MenuItem $item Specifies the menu item.
* @param \Cms\Classes\Theme $theme Specifies the current theme.
* @param string $url Specifies the current page URL, normalized, in lower case
* The URL is specified relative to the website root, it includes the subdirectory name, if any.
* @return mixed Returns an array. Returns null if the item cannot be resolved.
*/
public static function resolveMenuItem($item, $url, $theme)
{
$result = null;
if ($item->type == 'blog-post') {
if (!$item->reference || !$item->cmsPage) {
return;
}
$category = self::find($item->reference);
if (!$category) {
return;
}
$pageUrl = self::getPostPageUrl($item->cmsPage, $category, $theme);
if (!$pageUrl) {
return;
}
$pageUrl = Url::to($pageUrl);
$result = [];
$result['url'] = $pageUrl;
$result['isActive'] = $pageUrl == $url;
$result['mtime'] = $category->updated_at;
}
elseif ($item->type == 'all-blog-posts') {
$result = [
'items' => []
];
$posts = self::isPublished()
->orderBy('title')
->get()
;
foreach ($posts as $post) {
$postItem = [
'title' => $post->title,
'url' => self::getPostPageUrl($item->cmsPage, $post, $theme),
'mtime' => $post->updated_at
];
$postItem['isActive'] = $postItem['url'] == $url;
$result['items'][] = $postItem;
}
}
elseif ($item->type == 'category-blog-posts') {
if (!$item->reference || !$item->cmsPage) {
return;
}
$category = Category::find($item->reference);
if (!$category) {
return;
}
$result = [
'items' => []
];
$query = self::isPublished()
->orderBy('title');
$categories = $category->getAllChildrenAndSelf()->lists('id');
$query->whereHas('categories', function($q) use ($categories) {
$q->withoutGlobalScope(NestedTreeScope::class)->whereIn('id', $categories);
});
$posts = $query->get();
foreach ($posts as $post) {
$postItem = [
'title' => $post->title,
'url' => self::getPostPageUrl($item->cmsPage, $post, $theme),
'mtime' => $post->updated_at
];
$postItem['isActive'] = $postItem['url'] == $url;
$result['items'][] = $postItem;
}
}
return $result;
}
/**
* Returns URL of a post page.
*
* @param $pageCode
* @param $category
* @param $theme
*/
protected static function getPostPageUrl($pageCode, $category, $theme)
{
$page = CmsPage::loadCached($theme, $pageCode);
if (!$page) {
return;
}
$properties = $page->getComponentProperties('blogPost');
if (!isset($properties['slug'])) {
return;
}
/*
* Extract the routing parameter name from the category filter
* eg: {{ :someRouteParam }}
*/
if (!preg_match('/^\{\{([^\}]+)\}\}$/', $properties['slug'], $matches)) {
return;
}
$paramName = substr(trim($matches[1]), 1);
$params = [
$paramName => $category->slug,
'year' => $category->published_at->format('Y'),
'month' => $category->published_at->format('m'),
'day' => $category->published_at->format('d')
];
$url = CmsPage::url($page->getBaseFileName(), $params);
return $url;
}
}

View File

@ -0,0 +1,94 @@
<?php namespace RainLab\Blog\Models;
use Backend\Models\ExportModel;
use ApplicationException;
/**
* Post Export Model
*/
class PostExport extends ExportModel
{
public $table = 'rainlab_blog_posts';
/**
* @var array Relations
*/
public $belongsTo = [
'post_user' => [
'Backend\Models\User',
'key' => 'user_id'
]
];
public $belongsToMany = [
'post_categories' => [
'RainLab\Blog\Models\Category',
'table' => 'rainlab_blog_posts_categories',
'key' => 'post_id',
'otherKey' => 'category_id'
]
];
public $hasMany = [
'featured_images' => [
'System\Models\File',
'order' => 'sort_order',
'key' => 'attachment_id',
'conditions' => "field = 'featured_images' AND attachment_type = 'RainLab\\\\Blog\\\\Models\\\\Post'"
]
];
/**
* The accessors to append to the model's array form.
* @var array
*/
protected $appends = [
'author_email',
'categories',
'featured_image_urls'
];
public function exportData($columns, $sessionKey = null)
{
$result = self::make()
->with([
'post_user',
'post_categories',
'featured_images'
])
->get()
->toArray()
;
return $result;
}
public function getAuthorEmailAttribute()
{
if (!$this->post_user) {
return '';
}
return $this->post_user->email;
}
public function getCategoriesAttribute()
{
if (!$this->post_categories) {
return '';
}
return $this->encodeArrayValue($this->post_categories->lists('name'));
}
public function getFeaturedImageUrlsAttribute()
{
if (!$this->featured_images) {
return '';
}
return $this->encodeArrayValue($this->featured_images->map(function ($image) {
return $image->getPath();
}));
}
}

View File

@ -0,0 +1,165 @@
<?php namespace RainLab\Blog\Models;
use Backend\Models\ImportModel;
use Backend\Models\User as AuthorModel;
use ApplicationException;
use Exception;
/**
* Post Import Model
*/
class PostImport extends ImportModel
{
public $table = 'rainlab_blog_posts';
/**
* Validation rules
*/
public $rules = [
'title' => 'required',
'content' => 'required'
];
protected $authorEmailCache = [];
protected $categoryNameCache = [];
public function getDefaultAuthorOptions()
{
return AuthorModel::all()->lists('full_name', 'email');
}
public function getCategoriesOptions()
{
return Category::lists('name', 'id');
}
public function importData($results, $sessionKey = null)
{
$firstRow = reset($results);
/*
* Validation
*/
if ($this->auto_create_categories && !array_key_exists('categories', $firstRow)) {
throw new ApplicationException('Please specify a match for the Categories column.');
}
/*
* Import
*/
foreach ($results as $row => $data) {
try {
if (!$title = array_get($data, 'title')) {
$this->logSkipped($row, 'Missing post title');
continue;
}
/*
* Find or create
*/
$post = Post::make();
if ($this->update_existing) {
$post = $this->findDuplicatePost($data) ?: $post;
}
$postExists = $post->exists;
/*
* Set attributes
*/
$except = ['id', 'categories', 'author_email'];
foreach (array_except($data, $except) as $attribute => $value) {
if (in_array($attribute, $post->getDates()) && empty($value)) {
continue;
}
$post->{$attribute} = isset($value) ? $value : null;
}
if ($author = $this->findAuthorFromEmail($data)) {
$post->user_id = $author->id;
}
$post->forceSave();
if ($categoryIds = $this->getCategoryIdsForPost($data)) {
$post->categories()->sync($categoryIds, false);
}
/*
* Log results
*/
if ($postExists) {
$this->logUpdated();
}
else {
$this->logCreated();
}
}
catch (Exception $ex) {
$this->logError($row, $ex->getMessage());
}
}
}
protected function findAuthorFromEmail($data)
{
if (!$email = array_get($data, 'email', $this->default_author)) {
return null;
}
if (isset($this->authorEmailCache[$email])) {
return $this->authorEmailCache[$email];
}
$author = AuthorModel::where('email', $email)->first();
return $this->authorEmailCache[$email] = $author;
}
protected function findDuplicatePost($data)
{
if ($id = array_get($data, 'id')) {
return Post::find($id);
}
$title = array_get($data, 'title');
$post = Post::where('title', $title);
if ($slug = array_get($data, 'slug')) {
$post->orWhere('slug', $slug);
}
return $post->first();
}
protected function getCategoryIdsForPost($data)
{
$ids = [];
if ($this->auto_create_categories) {
$categoryNames = $this->decodeArrayValue(array_get($data, 'categories'));
foreach ($categoryNames as $name) {
if (!$name = trim($name)) {
continue;
}
if (isset($this->categoryNameCache[$name])) {
$ids[] = $this->categoryNameCache[$name];
}
else {
$newCategory = Category::firstOrCreate(['name' => $name]);
$ids[] = $this->categoryNameCache[$name] = $newCategory->id;
}
}
}
elseif ($this->categories) {
$ids = (array) $this->categories;
}
return $ids;
}
}

View File

@ -0,0 +1,18 @@
<?php namespace RainLab\Blog\Models;
use October\Rain\Database\Model;
class Settings extends Model
{
use \October\Rain\Database\Traits\Validation;
public $implement = ['System.Behaviors.SettingsModel'];
public $settingsCode = 'rainlab_blog_settings';
public $settingsFields = 'fields.yaml';
public $rules = [
'show_all_posts' => ['boolean'],
];
}

View File

@ -0,0 +1,13 @@
# ===================================
# Column Definitions
# ===================================
columns:
name:
label: rainlab.blog::lang.category.name
searchable: true
post_count:
label: rainlab.blog::lang.category.posts
sortable: false

View File

@ -0,0 +1,23 @@
# ===================================
# Field Definitions
# ===================================
fields:
name:
label: rainlab.blog::lang.category.name
placeholder: rainlab.blog::lang.category.name_placeholder
span: left
slug:
label: rainlab.blog::lang.category.slug
span: right
placeholder: rainlab.blog::lang.category.slug_placeholder
preset: name
description:
label: 'rainlab.blog::lang.category.description'
size: large
oc.commentPosition: ''
span: full
type: textarea

View File

@ -0,0 +1,36 @@
# ===================================
# Column Definitions
# ===================================
columns:
title:
label: rainlab.blog::lang.post.title
searchable: true
# author:
# label: Author
# relation: user
# select: login
# searchable: true
categories:
label: rainlab.blog::lang.post.categories
relation: categories
select: name
searchable: true
sortable: false
created_at:
label: rainlab.blog::lang.post.created
type: date
invisible: true
updated_at:
label: rainlab.blog::lang.post.updated
type: date
invisible: true
published_at:
label: rainlab.blog::lang.post.published
type: date

View File

@ -0,0 +1,77 @@
# ===================================
# Field Definitions
# ===================================
fields:
title:
label: rainlab.blog::lang.post.title
span: left
placeholder: rainlab.blog::lang.post.title_placeholder
slug:
label: rainlab.blog::lang.post.slug
span: right
placeholder: rainlab.blog::lang.post.slug_placeholder
preset:
field: title
type: slug
toolbar:
type: partial
path: post_toolbar
cssClass: collapse-visible
secondaryTabs:
stretch: true
fields:
content:
tab: rainlab.blog::lang.post.tab_edit
type: RainLab\Blog\FormWidgets\BlogMarkdown
cssClass: field-slim blog-post-preview
stretch: true
mode: split
# categories:
# tab: rainlab.blog::lang.post.tab_categories
# type: relation
# commentAbove: rainlab.blog::lang.post.categories_comment
# placeholder: rainlab.blog::lang.post.categories_placeholder
published:
tab: rainlab.blog::lang.post.tab_manage
label: rainlab.blog::lang.post.published
span: left
type: checkbox
user:
tab: rainlab.blog::lang.post.tab_manage
label: rainlab.blog::lang.post.published_by
span: right
type: dropdown
emptyOption: rainlab.blog::lang.post.current_user
published_at:
tab: rainlab.blog::lang.post.tab_manage
label: rainlab.blog::lang.post.published_on
span: left
cssClass: checkbox-align
type: datepicker
mode: datetime
trigger:
action: enable
field: published
condition: checked
excerpt:
tab: rainlab.blog::lang.post.tab_manage
label: rainlab.blog::lang.post.excerpt
type: textarea
size: small
featured_images:
tab: rainlab.blog::lang.post.tab_manage
label: rainlab.blog::lang.post.featured_images
type: fileupload
mode: image
imageWidth: 200
imageHeight: 200

View File

@ -0,0 +1,19 @@
# ===================================
# Column Definitions
# ===================================
columns:
id: ID
title: rainlab.blog::lang.post.title
content: rainlab.blog::lang.post.content
content_html: rainlab.blog::lang.post.content_html
excerpt: rainlab.blog::lang.post.excerpt
slug: rainlab.blog::lang.post.slug
categories: rainlab.blog::lang.post.categories
author_email: rainlab.blog::lang.post.author_email
featured_image_urls: rainlab.blog::lang.post.featured_images
created_at: rainlab.blog::lang.post.created_date
updated_at: rainlab.blog::lang.post.updated_date
published: rainlab.blog::lang.post.published
published_at: rainlab.blog::lang.post.published_date

View File

@ -0,0 +1,17 @@
# ===================================
# Column Definitions
# ===================================
columns:
id: ID
title: rainlab.blog::lang.post.title
content: rainlab.blog::lang.post.content
excerpt: rainlab.blog::lang.post.excerpt
slug: rainlab.blog::lang.post.slug
categories: rainlab.blog::lang.post.categories
author_email: rainlab.blog::lang.post.author_email
created_at: rainlab.blog::lang.post.created_date
updated_at: rainlab.blog::lang.post.updated_date
published: rainlab.blog::lang.post.published
published_at: rainlab.blog::lang.post.published_date

View File

@ -0,0 +1,37 @@
# ===================================
# Form Field Definitions
# ===================================
fields:
update_existing:
label: rainlab.blog::lang.import.update_existing_label
comment: rainlab.blog::lang.import.update_existing_comment
type: checkbox
default: true
span: left
auto_create_categories:
label: rainlab.blog::lang.import.auto_create_categories_label
comment: rainlab.blog::lang.import.auto_create_categories_comment
type: checkbox
default: true
span: right
categories:
label: rainlab.blog::lang.import.categories_label
commentAbove: rainlab.blog::lang.import.categories_comment
type: checkboxlist
span: right
cssClass: field-indent
trigger:
action: hide
field: auto_create_categories
condition: checked
default_author:
label: rainlab.blog::lang.import.default_author_label
comment: rainlab.blog::lang.import.default_author_comment
type: dropdown
placeholder: rainlab.blog::lang.import.default_author_placeholder
span: left

View File

@ -0,0 +1,9 @@
tabs:
fields:
show_all_posts:
span: left
label: rainlab.blog::lang.blog.show_all_posts_label
comment: rainlab.blog::lang.blog.show_all_posts_comment
type: switch
default: 1
tab: rainlab.blog::lang.blog.tab_general

View File

@ -0,0 +1,34 @@
<?php namespace RainLab\Blog\Updates;
use Schema;
use October\Rain\Database\Updates\Migration;
use RainLab\Blog\Models\Category as CategoryModel;
class CategoriesAddNestedFields extends Migration
{
public function up()
{
if (Schema::hasColumn('rainlab_blog_categories', 'parent_id')) {
return;
}
Schema::table('rainlab_blog_categories', function($table)
{
$table->integer('parent_id')->unsigned()->index()->nullable();
$table->integer('nest_left')->nullable();
$table->integer('nest_right')->nullable();
$table->integer('nest_depth')->nullable();
});
foreach (CategoryModel::all() as $category) {
$category->setDefaultLeftAndRight();
$category->save();
}
}
public function down()
{
}
}

View File

@ -0,0 +1,41 @@
<?php namespace RainLab\Blog\Updates;
use Schema;
use October\Rain\Database\Updates\Migration;
class CreateCategoriesTable extends Migration
{
public function up()
{
Schema::create('rainlab_blog_categories', function($table)
{
$table->engine = 'InnoDB';
$table->increments('id');
$table->string('name')->nullable();
$table->string('slug')->nullable()->index();
$table->string('code')->nullable();
$table->text('description')->nullable();
$table->integer('parent_id')->unsigned()->index()->nullable();
$table->integer('nest_left')->nullable();
$table->integer('nest_right')->nullable();
$table->integer('nest_depth')->nullable();
$table->timestamps();
});
Schema::create('rainlab_blog_posts_categories', function($table)
{
$table->engine = 'InnoDB';
$table->integer('post_id')->unsigned();
$table->integer('category_id')->unsigned();
$table->primary(['post_id', 'category_id']);
});
}
public function down()
{
Schema::dropIfExists('rainlab_blog_categories');
Schema::dropIfExists('rainlab_blog_posts_categories');
}
}

View File

@ -0,0 +1,32 @@
<?php namespace RainLab\Blog\Updates;
use Schema;
use October\Rain\Database\Updates\Migration;
class CreatePostsTable extends Migration
{
public function up()
{
Schema::create('rainlab_blog_posts', function($table)
{
$table->engine = 'InnoDB';
$table->increments('id');
$table->integer('user_id')->unsigned()->nullable()->index();
$table->string('title')->nullable();
$table->string('slug')->index();
$table->text('excerpt')->nullable();
$table->longText('content')->nullable();
$table->longText('content_html')->nullable();
$table->timestamp('published_at')->nullable();
$table->boolean('published')->default(false);
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('rainlab_blog_posts');
}
}

View File

@ -0,0 +1,31 @@
<?php namespace RainLab\Blog\Updates;
use Schema;
use October\Rain\Database\Updates\Migration;
use RainLab\Blog\Models\Category as CategoryModel;
class PostsAddMetadata extends Migration
{
public function up()
{
if (Schema::hasColumn('rainlab_blog_posts', 'metadata')) {
return;
}
Schema::table('rainlab_blog_posts', function($table)
{
$table->mediumText('metadata')->nullable();
});
}
public function down()
{
if (Schema::hasColumn('rainlab_blog_posts', 'metadata')) {
Schema::table('rainlab_blog_posts', function ($table) {
$table->dropColumn('metadata');
});
}
}
}

View File

@ -0,0 +1,34 @@
<?php namespace RainLab\Blog\Updates;
use Carbon\Carbon;
use RainLab\Blog\Models\Post;
use RainLab\Blog\Models\Category;
use October\Rain\Database\Updates\Seeder;
class SeedAllTables extends Seeder
{
public function run()
{
Post::create([
'title' => 'First blog post',
'slug' => 'first-blog-post',
'content' => '
This is your first ever **blog post**! It might be a good idea to update this post with some more relevant content.
You can edit this content by selecting **Blog** from the administration back-end menu.
*Enjoy the good times!*
',
'excerpt' => 'The first ever blog post is here. It might be a good idea to update this post with some more relevant content.',
'published_at' => Carbon::now(),
'published' => true
]);
Category::create([
'name' => trans('rainlab.blog::lang.categories.uncategorized'),
'slug' => 'uncategorized',
]);
}
}

View File

@ -0,0 +1,20 @@
<?php namespace RainLab\Blog\Updates;
use October\Rain\Database\Updates\Migration;
use DbDongle;
class UpdateTimestampsNullable extends Migration
{
public function up()
{
DbDongle::disableStrictMode();
DbDongle::convertTimestamps('rainlab_blog_posts');
DbDongle::convertTimestamps('rainlab_blog_categories');
}
public function down()
{
// ...
}
}

View File

@ -0,0 +1,62 @@
1.0.1:
- Initialize plugin.
- create_posts_table.php
- create_categories_table.php
- seed_all_tables.php
1.0.2: Added the processed HTML content column to the posts table.
1.0.3: Category component has been merged with Posts component.
1.0.4: Improvements to the Posts list management UI.
1.0.5: Removes the Author column from blog post list.
1.0.6: Featured images now appear in the Post component.
1.0.7: Added support for the Static Pages menus.
1.0.8: Added total posts to category list.
1.0.9: Added support for the Sitemap plugin.
1.0.10: Added permission to prevent users from seeing posts they did not create.
1.0.11: Deprecate "idParam" component property in favour of "slug" property.
1.0.12: Fixes issue where images cannot be uploaded caused by latest Markdown library.
1.0.13: Fixes problem with providing pages to Sitemap and Pages plugins.
1.0.14: Add support for CSRF protection feature added to core.
1.1.0: Replaced the Post editor with the new core Markdown editor.
1.1.1: Posts can now be imported and exported.
1.1.2: Posts are no longer visible if the published date has not passed.
1.1.3: Added a New Post shortcut button to the blog menu.
1.2.0:
- Categories now support nesting.
- categories_add_nested_fields.php
1.2.1: Post slugs now must be unique.
1.2.2: Fixes issue on new installs.
1.2.3: Minor user interface update.
1.2.4:
- Database maintenance. Updated all timestamp columns to be nullable.
- update_timestamp_nullable.php
1.2.5: Added translation support for blog posts.
1.2.6: The published field can now supply a time with the date.
1.2.7: Introduced a new RSS feed component.
1.2.8: Fixes issue with translated `content_html` attribute on blog posts.
1.2.9: Added translation support for blog categories.
1.2.10: Added translation support for post slugs.
1.2.11: Fixes bug where excerpt is not translated.
1.2.12: Description field added to category form.
1.2.13: Improved support for Static Pages menus, added a blog post and all blog posts.
1.2.14: Added post exception property to the post list component, useful for showing related posts.
1.2.15: Back-end navigation sort order updated.
1.2.16: Added `nextPost` and `previousPost` to the blog post component.
1.2.17: Improved the next and previous logic to sort by the published date.
1.2.18: Minor change to internals.
1.2.19: Improved support for Build 420+
1.3.0:
- Added metadata column for plugins to store data in
- posts_add_metadata.php
1.3.1: Fixed metadata column not being jsonable
1.3.2: Allow custom slug name for components, add 404 handling for missing blog posts, allow exporting of blog images.
1.3.3: Fixed 'excluded categories' filter from being run when value is empty.
1.3.4: Allow post author to be specified. Improved translations.
1.3.5: Fixed missing user info from breaking initial seeder in migrations. Fixed a PostgreSQL issue with blog exports.
1.3.6: Improved French translations.
1.4.0: Stability improvements. Rollback custom slug names for components
1.4.1: Fixes potential security issue with unsafe Markdown. Allow blog bylines to be translated.
1.4.2: Fix 404 redirects for missing blog posts. Assign current category to the listed posts when using the Posts component on a page with the category parameter available.
1.4.3: Fixes incompatibility with locale switching when plugin is used in conjunction with the Translate plugin. Fixes undefined category error.
1.4.4: Rollback translated bylines, please move or override the default component markup instead.
1.5.0: Implement support for October CMS v2.0
1.5.1: Fixes interaction with Translate plugin

View File

@ -2575,6 +2575,23 @@ li {
margin-top: 40px;
}
.news_row {
margin-bottom: 50px;
display: flex;
align-items: center;
justify-content: space-between;
}
.news_row .main_title {
margin-bottom: 0 !important;
}
.all_news {
font-size: 16px;
font-weight: 500;
line-height: 1.4;
}
.news_box {
display: flex;
flex-wrap: wrap;
@ -3204,7 +3221,7 @@ li {
-o-object-fit: contain;
}
.news_post-info-txt {
.news_post-info-txt p {
margin-bottom: 15px;
font-size: 16px;
line-height: 26px;
@ -6054,7 +6071,7 @@ input::-webkit-calendar-picker-indicator {
height: 350px;
}
.news_post-info-txt {
.news_post-info-txt p {
font-size: 14px;
}

View File

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="9" viewBox="0 0 12 9">
<g id="arrow-right" transform="translate(-2.75 -5.183)">
<path id="Path_3392" data-name="Path 3392" d="M14.28,14.183a.663.663,0,0,1-.424-.145.439.439,0,0,1,0-.7l4.431-3.656L13.857,6.026a.439.439,0,0,1,0-.7.7.7,0,0,1,.848,0l4.855,4.006a.439.439,0,0,1,0,.7L14.7,14.037A.663.663,0,0,1,14.28,14.183Z" transform="translate(-4.983 0)" fill="#fff"/>
<path id="Path_3393" data-name="Path 3393" d="M14.13,12.45H3.236a.613.613,0,0,1,0-1.2H14.13a.613.613,0,0,1,0,1.2Z" transform="translate(0 -2.168)" fill="#fff"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 610 B

View File

@ -3,6 +3,10 @@ en:
site.refresh: Refresh
site.name: Turkmenistan state birzha
site.short_name: ГТСБТ
site.news: News
site.last_news: Last News
site.all_news: All news
site.categories: Categories
auth.login: Enter email or phone number
auth.name: Name
auth.surname: Surname
@ -169,6 +173,10 @@ ru:
site.refresh: Обновить
site.name: '«Туркменистан: золотой век»'
site.short_name: ГТСБТ
site.news: Новости
site.last_news: Последние новости
site.all_news: Все новости
site.categories: Секции
auth.name: Ваша имя
auth.surname: Фамилия
auth.login: Введите почту или номер телефона
@ -335,6 +343,10 @@ tm:
site.refresh: Täzelemek
site.name: Türkmenistanyň Döwlet çig-mal biržasy
site.short_name: TDÇMB
site.news: Habarlar
site.last_news: Soňky habarlar
site.all_news: Hemme habarlar
site.categories: Pudaklar
auth.name: Adyňyz
auth.surname: Familiýaňyz
auth.login: El. bukjaňyz ýa-da telefon nomeriňiz

View File

@ -22,6 +22,14 @@ sortOrder = "desc"
active = 1
slug = "{{ :slug }}"
renderFeatures = "with_images"
[blogPosts]
pageNumber = "{{ :page }}"
postsPerPage = 3
noPostsMessage = "No posts found"
sortOrder = "published_at desc"
categoryPage = 404
postPage = "news_post"
==
{% put styles %}
<link rel="stylesheet" href="{{['assets/css/slick-theme.css','assets/css/slick.css']|theme}}">
@ -36,7 +44,7 @@ renderFeatures = "with_images"
{% partial 'slider' %}
{% component 'categories' %}
</div>
@ -44,6 +52,68 @@ renderFeatures = "with_images"
</section>
<!--Intro end ========================================================= -->
<!--News ============================================================= -->
<section class="news">
<div class="auto_container">
<div class="news_wrap">
<div class="news_row">
<h3 class="main_title">
{{ 'site.last_news'|_ }}
</h3>
<a href="{{'novosti'|page}}" class="all_news">
{{ 'site.all_news'|_ }}
</a>
</div>
<div class="news_box">
{% set posts = blogPosts.posts %}
{% for post in posts %}
<div class="news_box-item wow fadeInUp" data-wow-duration=".5s" data-wow-delay=".1s">
<div class="news_box-item-photo">
<img src="{{ post.featured_images[0].thumb(467,300,{'mode':'crop'}) }}" alt="news-photo">
<a href="{{ post.url }}" class="news_link">
<img src="{{ 'assets/images/svg/news_arrow.svg'|theme }}" alt="arrow-icon">
</a>
</div>
<a href="{{ post.url }}" class="news_box-item-title">
{{ post.title }}
</a>
<p class="news_box-item-date">
{{ post.published_at|date('d.m.Y') }}
</p>
<p class="news_box-item-txt">
{{ post.excerpt }}
</p>
</div>
{% endfor %}
</div>
</div>
</div>
</section>
<!--News end ========================================================= -->
<!--Intro ============================================================= -->
<section class="category_block">
<div class="auto_container">
<div class="category_wrap">
<h3 class="main_title">
{{ 'site.categories'|_ }}
</h3>
{% component 'categories' %}
</div>
</div>
</section>
<!--Intro end ========================================================= -->
<!--Product ============================================================= -->
<section class="product">
<div class="auto_container">

View File

@ -0,0 +1,75 @@
title = "Habar"
url = "/habar/:id/:slug"
layout = "default"
is_hidden = 0
[viewBag]
localeTitle[en] = "News"
localeTitle[ru] = "Новость"
localeUrl[en] = "/news/:id/:slug"
localeUrl[ru] = "/novost/:id/:slug"
[blogPost]
slug = "{{ :slug }}"
id = "{{ :id }}"
categoryPage = 404
[blogPosts]
pageNumber = "{{ :page }}"
postsPerPage = 6
noPostsMessage = "No posts found"
sortOrder = "published_at desc"
categoryPage = 404
postPage = "news_post"
exceptPost = "{{ :id }}"
==
{% set post = blogPost.post %}
<!-- New post ========================================================= -->
<section class="news_post">
<div class="auto_container">
<div class="news_post-wrap">
<div class="news_post-box">
<div class="news_post-info">
<h4 class="news_post-info-title">
{{ post.title }}
</h4>
<p class="news_post-info-date">
{{ post.published_at|date('d.m.Y') }}
</p>
<div class="news_post-info-photo">
<img src="{{ post.featured_images[0].thumb(990,500,{'mode':'crop'}) }}" alt="news-photo">
</div>
<div class="news_post-info-txt">
{{ post.content_html|raw }}
</div>
</div>
<div class="news_post-aside">
<h1 class="news_aside-title">
{{ 'site.last_news'|_ }}
</h1>
{% set asidePosts = blogPosts.posts %}
{% for asidePost in asidePosts %}
<div class="news_aside-item">
<p class="news_aside-item-date">
{{ asidePost.published_at|date('d.m.Y') }}
</p>
<a href="{{ asidePost.url }}" class="news_aside-item-title">
{{ asidePost.title }}
</a>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
</section>
<!-- New post end ========================================================= -->

View File

@ -0,0 +1,77 @@
title = "Habarlar"
url = "/habarlar/:page?"
layout = "default"
is_hidden = 0
[viewBag]
localeTitle[en] = "News"
localeTitle[ru] = "Новости"
localeUrl[en] = "/news/:page?"
localeUrl[ru] = "/novosti/:page?"
[blogPosts]
pageNumber = "{{ :page }}"
postsPerPage = 6
noPostsMessage = "No posts found"
sortOrder = "published_at desc"
categoryPage = 404
postPage = "news_post"
==
{% set posts = blogPosts.posts %}
<!--News ============================================================= -->
<section class="news news_page">
<div class="auto_container">
<div class="news_wrap">
<h3 class="main_title">
{{ 'site.news'|_ }}
</h3>
<div class="news_box">
{% for post in posts %}
<div class="news_box-item wow fadeInUp" data-wow-duration=".5s" data-wow-delay=".2s">
<div class="news_box-item-photo">
<img src="{{ post.featured_images[0].thumb(467,300,{'mode':'crop'}) }}" alt="news-photo">
<a href="{{ post.url }}" class="news_link">
<img src="{{ 'assets/images/svg/news_arrow.svg'|theme }}" alt="arrow-icon">
</a>
</div>
<a href="{{ post.url }}" class="news_box-item-title">
{{ post.title }}
</a>
<p class="news_box-item-date">
{{ post.published_at|date('d.m.Y') }}
</p>
<p class="news_box-item-txt">
{{ post.excerpt }}
</p>
</div>
{% endfor %}
</div>
{% if posts.lastPage > 1 %}
<div class="cat_end">
{% if posts.currentPage > 1 %}
<a href="{{ this.page.baseFileName|page({ (blogPosts.pageParam): (posts.currentPage-1) }) }}" class="cat_arrow left">
<img src="{{ 'assets/images/svg/arrow-right.svg'|theme }}" alt="">
</a>
{% endif %}
<form action="#" class="cat_form">
<input type="text" placeholder="{{ posts.currentPage }}">
</form>
{% if posts.lastPage > posts.currentPage %}
<a href="{{ this.page.baseFileName|page({ (blogPosts.pageParam): (posts.currentPage+1) }) }}" class="cat_arrow ">
<img src="{{ 'assets/images/svg/arrow-right.svg'|theme }}" alt="">
</a>
{% endif %}
<div class="cat_page">
{{ posts.lastPage }} {{ 'page.pages'|_ }}
</div>
</div>
{% endif %}
</div>
</div>
</section>
<!--News end ========================================================= -->