Browse Source

blogging module : Added blog management page

pull/441/head
Yunus Emre Kalkan 8 years ago
parent
commit
09b336aaa4
  1. 25
      framework/src/Volo.Abp.Core/Volo/Abp/Modularity/AbpModule.cs
  2. 625
      modules/blogging/app/Volo.BloggingTestApp.EntityFrameworkCore/Migrations/20180912113852_Added_BlogUsers.Designer.cs
  3. 35
      modules/blogging/app/Volo.BloggingTestApp.EntityFrameworkCore/Migrations/20180912113852_Added_BlogUsers.cs
  4. 39
      modules/blogging/app/Volo.BloggingTestApp.EntityFrameworkCore/Migrations/BloggingTestAppDbContextModelSnapshot.cs
  5. 16
      modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/BloggingApplicationContractsModule.cs
  6. 1
      modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/BloggingPermissions.cs
  7. 4
      modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Blogs/Dtos/BlogDto.cs
  8. 5
      modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Blogs/Dtos/CreateBlogDto.cs
  9. 15
      modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Blogs/Dtos/UpdateBlogDto.cs
  10. 13
      modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Blogs/IBlogAppService.cs
  11. 1
      modules/blogging/src/Volo.Blogging.Application/Volo/Blogging/BloggingApplicationAutoMapperProfile.cs
  12. 29
      modules/blogging/src/Volo.Blogging.Application/Volo/Blogging/Blogs/BlogAppService.cs
  13. 14
      modules/blogging/src/Volo.Blogging.Application/Volo/Blogging/Posts/PostAppService.cs
  14. 1
      modules/blogging/src/Volo.Blogging.Domain/Volo.Blogging.Domain.csproj
  15. 6
      modules/blogging/src/Volo.Blogging.Domain/Volo/Blogging/Blogs/Blog.cs
  16. 5
      modules/blogging/src/Volo.Blogging.Domain/Volo/Blogging/Blogs/IBlogRepository.cs
  17. 43
      modules/blogging/src/Volo.Blogging.Domain/Volo/Blogging/Users/BlogUser.cs
  18. 22
      modules/blogging/src/Volo.Blogging.Domain/Volo/Blogging/Users/BlogUserLookupService.cs
  19. 9
      modules/blogging/src/Volo.Blogging.Domain/Volo/Blogging/Users/IBlogUserLookupService.cs
  20. 14
      modules/blogging/src/Volo.Blogging.Domain/Volo/Blogging/Users/IBlogUserRepository.cs
  21. 1
      modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo.Blogging.EntityFrameworkCore.csproj
  22. 17
      modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/Blogs/EfCoreBlogRepository.cs
  23. 3
      modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/EntityFrameworkCore/BloggingDbContext.cs
  24. 10
      modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/EntityFrameworkCore/BloggingDbContextModelBuilderExtensions.cs
  25. 3
      modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/EntityFrameworkCore/IBloggingDbContext.cs
  26. 27
      modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/Users/EfCoreQaUserRepository.cs
  27. 1
      modules/blogging/src/Volo.Blogging.HttpApi.Client/Volo.Blogging.HttpApi.Client.csproj
  28. 10
      modules/blogging/src/Volo.Blogging.HttpApi.Client/Volo/Blogging/BloggingHttpApiClientModule.cs
  29. 1
      modules/blogging/src/Volo.Blogging.HttpApi/Volo.Blogging.HttpApi.csproj
  30. 5
      modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/BloggingHttpApiModule.cs
  31. 77
      modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/BlogsController.cs
  32. 5
      modules/blogging/src/Volo.Blogging.Web/AbpBloggingWebAutoMapperProfile.cs
  33. 7
      modules/blogging/src/Volo.Blogging.Web/BloggingMenuContributor.cs
  34. 8
      modules/blogging/src/Volo.Blogging.Web/BloggingWebModule.cs
  35. 1
      modules/blogging/src/Volo.Blogging.Web/Localization/Resources/Blogging/Web/en.json
  36. 1
      modules/blogging/src/Volo.Blogging.Web/Localization/Resources/Blogging/Web/tr.json
  37. 20
      modules/blogging/src/Volo.Blogging.Web/Pages/Admin/Blogs/Create.cshtml
  38. 50
      modules/blogging/src/Volo.Blogging.Web/Pages/Admin/Blogs/Create.cshtml.cs
  39. 20
      modules/blogging/src/Volo.Blogging.Web/Pages/Admin/Blogs/Edit.cshtml
  40. 65
      modules/blogging/src/Volo.Blogging.Web/Pages/Admin/Blogs/Edit.cshtml.cs
  41. 44
      modules/blogging/src/Volo.Blogging.Web/Pages/Admin/Blogs/Index.cshtml
  42. 12
      modules/blogging/src/Volo.Blogging.Web/Pages/Admin/Blogs/Index.cshtml.cs
  43. 14
      modules/blogging/src/Volo.Blogging.Web/Pages/Admin/Blogs/create.js
  44. 14
      modules/blogging/src/Volo.Blogging.Web/Pages/Admin/Blogs/edit.js
  45. 85
      modules/blogging/src/Volo.Blogging.Web/Pages/Admin/Blogs/index.js
  46. 1
      modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Index.cshtml.cs
  47. 385
      modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Posts/Detail.cshtml
  48. 1
      modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Posts/Detail.cshtml.cs
  49. 289
      modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Posts/Index.cshtml
  50. 1
      modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Posts/New.cshtml.cs
  51. 9
      modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Posts/new.css.map
  52. 3
      modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Posts/new.min.css
  53. 2
      modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Shared/Scripts/blog.js
  54. 169
      modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Shared/Styles/_bootstrap-overwrite.scss
  55. 40
      modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Shared/Styles/_header.scss
  56. 140
      modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Shared/Styles/_home.css
  57. 1
      modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Shared/Styles/_home.min.css
  58. 88
      modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Shared/Styles/_home.scss
  59. 30
      modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Shared/Styles/_post.scss
  60. 289
      modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Shared/Styles/blog.css
  61. 24
      modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Shared/Styles/blog.css.map
  62. 2
      modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Shared/Styles/blog.min.css
  63. 18
      modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Shared/Styles/blog.scss
  64. 2
      modules/blogging/src/Volo.Blogging.Web/Volo.Blogging.Web.csproj
  65. 4
      modules/blogging/src/Volo.Blogging.Web/compilerconfig.json

25
framework/src/Volo.Abp.Core/Volo/Abp/Modularity/AbpModule.cs

@ -1,5 +1,6 @@
using System;
using System.Reflection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace Volo.Abp.Modularity
@ -91,6 +92,30 @@ namespace Volo.Abp.Modularity
ServiceConfigurationContext.Services.Configure(configureOptions);
}
protected void Configure<TOptions>(string name, Action<TOptions> configureOptions)
where TOptions : class
{
ServiceConfigurationContext.Services.Configure(name, configureOptions);
}
protected void Configure<TOptions>(IConfiguration configuration)
where TOptions : class
{
ServiceConfigurationContext.Services.Configure<TOptions>(configuration);
}
protected void Configure<TOptions>(IConfiguration configuration, Action<BinderOptions> configureBinder)
where TOptions : class
{
ServiceConfigurationContext.Services.Configure<TOptions>(configuration, configureBinder);
}
protected void Configure<TOptions>(string name, IConfiguration configuration)
where TOptions : class
{
ServiceConfigurationContext.Services.Configure<TOptions>(name, configuration);
}
protected void PreConfigure<TOptions>(Action<TOptions> configureOptions)
where TOptions : class
{

625
modules/blogging/app/Volo.BloggingTestApp.EntityFrameworkCore/Migrations/20180912113852_Added_BlogUsers.Designer.cs

@ -0,0 +1,625 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Volo.BloggingTestApp.EntityFrameworkCore;
namespace Volo.BloggingTestApp.EntityFrameworkCore.Migrations
{
[DbContext(typeof(BloggingTestAppDbContext))]
[Migration("20180912113852_Added_BlogUsers")]
partial class Added_BlogUsers
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "2.1.1-rtm-30846")
.HasAnnotation("Relational:MaxIdentifierLength", 128)
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("ConcurrencyStamp");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(256);
b.Property<string>("NormalizedName")
.IsRequired()
.HasMaxLength(256);
b.Property<Guid?>("TenantId");
b.HasKey("Id");
b.HasIndex("NormalizedName");
b.ToTable("AbpRoles");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("ClaimType")
.IsRequired()
.HasMaxLength(256);
b.Property<string>("ClaimValue")
.HasMaxLength(1024);
b.Property<Guid>("RoleId");
b.Property<Guid?>("TenantId");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AbpRoleClaims");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("AccessFailedCount")
.ValueGeneratedOnAdd()
.HasColumnName("AccessFailedCount")
.HasDefaultValue(0);
b.Property<string>("ConcurrencyStamp")
.IsRequired()
.HasColumnName("ConcurrencyStamp")
.HasMaxLength(256);
b.Property<string>("Email")
.HasColumnName("Email")
.HasMaxLength(256);
b.Property<bool>("EmailConfirmed")
.ValueGeneratedOnAdd()
.HasColumnName("EmailConfirmed")
.HasDefaultValue(false);
b.Property<string>("ExtraProperties")
.HasColumnName("ExtraProperties");
b.Property<bool>("LockoutEnabled")
.ValueGeneratedOnAdd()
.HasColumnName("LockoutEnabled")
.HasDefaultValue(false);
b.Property<DateTimeOffset?>("LockoutEnd");
b.Property<string>("NormalizedEmail")
.HasColumnName("NormalizedEmail")
.HasMaxLength(256);
b.Property<string>("NormalizedUserName")
.IsRequired()
.HasColumnName("NormalizedUserName")
.HasMaxLength(256);
b.Property<string>("PasswordHash")
.HasColumnName("PasswordHash")
.HasMaxLength(256);
b.Property<string>("PhoneNumber")
.HasColumnName("PhoneNumber")
.HasMaxLength(16);
b.Property<bool>("PhoneNumberConfirmed")
.ValueGeneratedOnAdd()
.HasColumnName("PhoneNumberConfirmed")
.HasDefaultValue(false);
b.Property<string>("SecurityStamp")
.IsRequired()
.HasColumnName("SecurityStamp")
.HasMaxLength(256);
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId");
b.Property<bool>("TwoFactorEnabled")
.ValueGeneratedOnAdd()
.HasColumnName("TwoFactorEnabled")
.HasDefaultValue(false);
b.Property<string>("UserName")
.IsRequired()
.HasColumnName("UserName")
.HasMaxLength(256);
b.HasKey("Id");
b.HasIndex("Email");
b.HasIndex("NormalizedEmail");
b.HasIndex("NormalizedUserName");
b.HasIndex("UserName");
b.ToTable("AbpUsers");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("ClaimType")
.IsRequired()
.HasMaxLength(256);
b.Property<string>("ClaimValue")
.HasMaxLength(1024);
b.Property<Guid?>("TenantId");
b.Property<Guid>("UserId");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AbpUserClaims");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b =>
{
b.Property<Guid>("UserId");
b.Property<string>("LoginProvider")
.HasMaxLength(64);
b.Property<string>("ProviderDisplayName")
.HasMaxLength(128);
b.Property<string>("ProviderKey")
.IsRequired()
.HasMaxLength(196);
b.Property<Guid?>("TenantId");
b.HasKey("UserId", "LoginProvider");
b.HasIndex("LoginProvider", "ProviderKey");
b.ToTable("AbpUserLogins");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b =>
{
b.Property<Guid>("UserId");
b.Property<Guid>("RoleId");
b.Property<Guid?>("TenantId");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId", "UserId");
b.ToTable("AbpUserRoles");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b =>
{
b.Property<Guid>("UserId");
b.Property<string>("LoginProvider")
.HasMaxLength(128);
b.Property<string>("Name");
b.Property<Guid?>("TenantId");
b.Property<string>("Value");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AbpUserTokens");
});
modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionGrant", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(128);
b.Property<string>("ProviderKey")
.IsRequired()
.HasMaxLength(64);
b.Property<string>("ProviderName")
.IsRequired()
.HasMaxLength(64);
b.Property<Guid?>("TenantId");
b.HasKey("Id");
b.HasIndex("Name", "ProviderName", "ProviderKey");
b.ToTable("AbpPermissionGrants");
});
modelBuilder.Entity("Volo.Abp.SettingManagement.Setting", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(128);
b.Property<string>("ProviderKey")
.HasMaxLength(64);
b.Property<string>("ProviderName")
.HasMaxLength(64);
b.Property<string>("Value")
.IsRequired()
.HasMaxLength(2048);
b.HasKey("Id");
b.HasIndex("Name", "ProviderName", "ProviderKey");
b.ToTable("AbpSettings");
});
modelBuilder.Entity("Volo.Blogging.Blogs.Blog", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<DateTime>("CreationTime")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnName("CreatorId");
b.Property<Guid?>("DeleterId")
.HasColumnName("DeleterId");
b.Property<DateTime?>("DeletionTime")
.HasColumnName("DeletionTime");
b.Property<string>("Description")
.HasColumnName("Description")
.HasMaxLength(1024);
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnName("IsDeleted")
.HasDefaultValue(false);
b.Property<DateTime?>("LastModificationTime")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnName("LastModifierId");
b.Property<string>("Name")
.IsRequired()
.HasColumnName("Name")
.HasMaxLength(256);
b.Property<string>("ShortName")
.IsRequired()
.HasColumnName("ShortName")
.HasMaxLength(32);
b.HasKey("Id");
b.ToTable("BlgBlogs");
});
modelBuilder.Entity("Volo.Blogging.Comments.Comment", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<DateTime>("CreationTime")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnName("CreatorId");
b.Property<Guid?>("DeleterId")
.HasColumnName("DeleterId");
b.Property<DateTime?>("DeletionTime")
.HasColumnName("DeletionTime");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnName("IsDeleted")
.HasDefaultValue(false);
b.Property<DateTime?>("LastModificationTime")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnName("LastModifierId");
b.Property<Guid>("PostId")
.HasColumnName("PostId");
b.Property<Guid?>("RepliedCommentId")
.HasColumnName("RepliedCommentId");
b.Property<string>("Text")
.IsRequired()
.HasColumnName("Text")
.HasMaxLength(1024);
b.HasKey("Id");
b.HasIndex("PostId");
b.HasIndex("RepliedCommentId");
b.ToTable("BlgComments");
});
modelBuilder.Entity("Volo.Blogging.Posts.Post", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<Guid>("BlogId")
.HasColumnName("BlogId");
b.Property<string>("Content")
.HasColumnName("Content")
.HasMaxLength(1048576);
b.Property<string>("CoverImage")
.IsRequired()
.HasColumnName("CoverImage");
b.Property<DateTime>("CreationTime")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnName("CreatorId");
b.Property<Guid?>("DeleterId")
.HasColumnName("DeleterId");
b.Property<DateTime?>("DeletionTime")
.HasColumnName("DeletionTime");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnName("IsDeleted")
.HasDefaultValue(false);
b.Property<DateTime?>("LastModificationTime")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnName("LastModifierId");
b.Property<int>("ReadCount");
b.Property<string>("Title")
.IsRequired()
.HasColumnName("Title")
.HasMaxLength(512);
b.Property<string>("Url")
.IsRequired()
.HasColumnName("Url")
.HasMaxLength(64);
b.HasKey("Id");
b.HasIndex("BlogId");
b.ToTable("BlgPosts");
});
modelBuilder.Entity("Volo.Blogging.Posts.PostTag", b =>
{
b.Property<Guid>("PostId")
.HasColumnName("PostId");
b.Property<Guid>("TagId")
.HasColumnName("TagId");
b.Property<DateTime>("CreationTime");
b.Property<Guid?>("CreatorId");
b.HasKey("PostId", "TagId");
b.HasIndex("TagId");
b.ToTable("BlgPostTags");
});
modelBuilder.Entity("Volo.Blogging.Tagging.Tag", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<DateTime>("CreationTime")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnName("CreatorId");
b.Property<Guid?>("DeleterId")
.HasColumnName("DeleterId");
b.Property<DateTime?>("DeletionTime")
.HasColumnName("DeletionTime");
b.Property<string>("Description")
.HasColumnName("Description")
.HasMaxLength(512);
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnName("IsDeleted")
.HasDefaultValue(false);
b.Property<DateTime?>("LastModificationTime")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnName("LastModifierId");
b.Property<string>("Name")
.IsRequired()
.HasColumnName("Name")
.HasMaxLength(64);
b.Property<int>("UsageCount")
.HasColumnName("UsageCount");
b.HasKey("Id");
b.ToTable("BlgTags");
});
modelBuilder.Entity("Volo.Blogging.Users.BlogUser", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("Email")
.HasColumnName("Email")
.HasMaxLength(256);
b.Property<bool>("EmailConfirmed")
.ValueGeneratedOnAdd()
.HasColumnName("EmailConfirmed")
.HasDefaultValue(false);
b.Property<string>("ExtraProperties")
.HasColumnName("ExtraProperties");
b.Property<string>("PhoneNumber")
.HasColumnName("PhoneNumber")
.HasMaxLength(16);
b.Property<bool>("PhoneNumberConfirmed")
.ValueGeneratedOnAdd()
.HasColumnName("PhoneNumberConfirmed")
.HasDefaultValue(false);
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId");
b.Property<string>("UserName")
.IsRequired()
.HasColumnName("UserName")
.HasMaxLength(256);
b.HasKey("Id");
b.ToTable("BlgUsers");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b =>
{
b.HasOne("Volo.Abp.Identity.IdentityRole")
.WithMany("Claims")
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b =>
{
b.HasOne("Volo.Abp.Identity.IdentityUser")
.WithMany("Claims")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b =>
{
b.HasOne("Volo.Abp.Identity.IdentityUser")
.WithMany("Logins")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b =>
{
b.HasOne("Volo.Abp.Identity.IdentityRole")
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("Volo.Abp.Identity.IdentityUser")
.WithMany("Roles")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b =>
{
b.HasOne("Volo.Abp.Identity.IdentityUser")
.WithMany("Tokens")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Volo.Blogging.Comments.Comment", b =>
{
b.HasOne("Volo.Blogging.Posts.Post")
.WithMany()
.HasForeignKey("PostId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("Volo.Blogging.Comments.Comment")
.WithMany()
.HasForeignKey("RepliedCommentId");
});
modelBuilder.Entity("Volo.Blogging.Posts.Post", b =>
{
b.HasOne("Volo.Blogging.Blogs.Blog")
.WithMany()
.HasForeignKey("BlogId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Volo.Blogging.Posts.PostTag", b =>
{
b.HasOne("Volo.Blogging.Posts.Post")
.WithMany("Tags")
.HasForeignKey("PostId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("Volo.Blogging.Tagging.Tag")
.WithMany()
.HasForeignKey("TagId")
.OnDelete(DeleteBehavior.Cascade);
});
#pragma warning restore 612, 618
}
}
}

35
modules/blogging/app/Volo.BloggingTestApp.EntityFrameworkCore/Migrations/20180912113852_Added_BlogUsers.cs

@ -0,0 +1,35 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace Volo.BloggingTestApp.EntityFrameworkCore.Migrations
{
public partial class Added_BlogUsers : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "BlgUsers",
columns: table => new
{
Id = table.Column<Guid>(nullable: false),
TenantId = table.Column<Guid>(nullable: true),
UserName = table.Column<string>(maxLength: 256, nullable: false),
Email = table.Column<string>(maxLength: 256, nullable: true),
EmailConfirmed = table.Column<bool>(nullable: false, defaultValue: false),
PhoneNumber = table.Column<string>(maxLength: 16, nullable: true),
PhoneNumberConfirmed = table.Column<bool>(nullable: false, defaultValue: false),
ExtraProperties = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_BlgUsers", x => x.Id);
});
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "BlgUsers");
}
}
}

39
modules/blogging/app/Volo.BloggingTestApp.EntityFrameworkCore/Migrations/BloggingTestAppDbContextModelSnapshot.cs

@ -501,6 +501,45 @@ namespace Volo.BloggingTestApp.EntityFrameworkCore.Migrations
b.ToTable("BlgTags");
});
modelBuilder.Entity("Volo.Blogging.Users.BlogUser", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("Email")
.HasColumnName("Email")
.HasMaxLength(256);
b.Property<bool>("EmailConfirmed")
.ValueGeneratedOnAdd()
.HasColumnName("EmailConfirmed")
.HasDefaultValue(false);
b.Property<string>("ExtraProperties")
.HasColumnName("ExtraProperties");
b.Property<string>("PhoneNumber")
.HasColumnName("PhoneNumber")
.HasMaxLength(16);
b.Property<bool>("PhoneNumberConfirmed")
.ValueGeneratedOnAdd()
.HasColumnName("PhoneNumberConfirmed")
.HasDefaultValue(false);
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId");
b.Property<string>("UserName")
.IsRequired()
.HasColumnName("UserName")
.HasMaxLength(256);
b.HasKey("Id");
b.ToTable("BlgUsers");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b =>
{
b.HasOne("Volo.Abp.Identity.IdentityRole")

16
modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/BloggingApplicationContractsModule.cs

@ -1,8 +1,8 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Localization;
using Volo.Abp.Localization.Resources.AbpValidation;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
using Volo.Blogging.Localization;
namespace Volo.Blogging
@ -12,17 +12,21 @@ namespace Volo.Blogging
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.Configure<PermissionOptions>(options =>
{
options.DefinitionProviders.Add<BloggingPermissionDefinitionProvider>();
});
context.Services.Configure<VirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<BloggingApplicationContractsModule>();
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Get<BloggingResource>()
.AddVirtualJson("/Localization/Resources/Blogging/ApplicationContracts");
});
context.Services.Configure<PermissionOptions>(options =>
{
options.DefinitionProviders.Add<BloggingPermissionDefinitionProvider>();
});
}
}
}

1
modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/BloggingPermissions.cs

@ -10,6 +10,7 @@
public const string Delete = Default + ".Delete";
public const string Update = Default + ".Update";
public const string Create = Default + ".Create";
}
public static class Posts

4
modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Blogs/BlogDto.cs → modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Blogs/Dtos/BlogDto.cs

@ -1,9 +1,9 @@
using System;
using Volo.Abp.Application.Dtos;
namespace Volo.Blogging.Blogs
namespace Volo.Blogging.Blogs.Dtos
{
public class BlogDto : EntityDto<Guid>
public class BlogDto : FullAuditedEntityDto<Guid>
{
public string Name { get; set; }

5
modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Blogs/CreateBlogDto.cs → modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Blogs/Dtos/CreateBlogDto.cs

@ -1,7 +1,4 @@
using System;
using Volo.Abp.Application.Dtos;
namespace Volo.Blogging.Blogs
namespace Volo.Blogging.Blogs.Dtos
{
public class CreateBlogDto
{

15
modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Blogs/Dtos/UpdateBlogDto.cs

@ -0,0 +1,15 @@
using System;
namespace Volo.Blogging.Blogs.Dtos
{
public class UpdateBlogDto
{
public Guid Id { get; set; }
public string Name { get; set; }
public string ShortName { get; set; }
public string Description { get; set; }
}
}

13
modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Blogs/IBlogAppService.cs

@ -2,17 +2,28 @@
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Blogging.Blogs.Dtos;
namespace Volo.Blogging.Blogs
{
public interface IBlogAppService : IApplicationService
{
Task<PagedResultDto<BlogDto>> GetListPagedAsync(PagedAndSortedResultRequestDto input);
Task<ListResultDto<BlogDto>> GetListAsync();
Task<BlogDto> GetByShortNameAsync(string shortName);
Task<BlogDto> GetAsync(Guid id);
Task Create(CreateBlogDto blog);
<<<<<<< HEAD
Task<BlogDto> Create(CreateBlogDto input);
Task<BlogDto> Update(Guid id, UpdateBlogDto input);
Task Delete(Guid id);
=======
Task<BlogDto> Create(CreateBlogDto blog);
>>>>>>> 5023d9202b64c4367e1234ad5e5f7acb76c592e3
}
}

1
modules/blogging/src/Volo.Blogging.Application/Volo/Blogging/BloggingApplicationAutoMapperProfile.cs

@ -1,6 +1,7 @@
using AutoMapper;
using Volo.Abp.AutoMapper;
using Volo.Blogging.Blogs;
using Volo.Blogging.Blogs.Dtos;
using Volo.Blogging.Comments;
using Volo.Blogging.Comments.Dtos;
using Volo.Blogging.Posts;

29
modules/blogging/src/Volo.Blogging.Application/Volo/Blogging/Blogs/BlogAppService.cs

@ -4,6 +4,7 @@ using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Entities;
using Volo.Blogging.Blogs.Dtos;
namespace Volo.Blogging.Blogs
{
@ -15,6 +16,18 @@ namespace Volo.Blogging.Blogs
{
_blogRepository = blogRepository;
}
public async Task<PagedResultDto<BlogDto>> GetListPagedAsync(PagedAndSortedResultRequestDto input)
{
var blogs = await _blogRepository.GetListAsync(input.Sorting, input.MaxResultCount, input.SkipCount );
var totalCount = await _blogRepository.GetTotalBlogCount();
var dtos = ObjectMapper.Map<List<Blog>, List<BlogDto>>(blogs);
return new PagedResultDto<BlogDto>(totalCount, dtos);
}
public async Task<ListResultDto<BlogDto>> GetListAsync()
{
var blogs = await _blogRepository.GetListAsync();
@ -49,5 +62,21 @@ namespace Volo.Blogging.Blogs
return ObjectMapper.Map<Blog, BlogDto>(newBlog);
}
public async Task<BlogDto> Update(Guid id, UpdateBlogDto input)
{
var blog = await _blogRepository.GetAsync(id);
blog.SetName(input.Name);
blog.SetShortName(input.ShortName);
blog.Description = input.Description;
return ObjectMapper.Map<Blog, BlogDto>(blog);
}
public async Task Delete(Guid id)
{
await _blogRepository.DeleteAsync(id);
}
}
}

14
modules/blogging/src/Volo.Blogging.Application/Volo/Blogging/Posts/PostAppService.cs

@ -5,10 +5,12 @@ using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using System.Collections.Generic;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Logging;
using Volo.Abp.Users;
using Volo.Blogging.Comments;
using Volo.Blogging.Tagging;
using Volo.Blogging.Tagging.Dtos;
using Volo.Blogging.Users;
namespace Volo.Blogging.Posts
{
@ -19,13 +21,16 @@ namespace Volo.Blogging.Posts
//[Authorize(BloggingPermissions.Posts.Default)]
public class PostAppService : ApplicationService, IPostAppService
{
protected IBlogUserLookupService UserLookupService { get; }
private readonly IPostRepository _postRepository;
private readonly ITagRepository _tagRepository;
private readonly IPostTagRepository _postTagRepository;
private readonly ICommentRepository _commentRepository;
public PostAppService(IPostRepository postRepository, ITagRepository tagRepository, IPostTagRepository postTagRepository, ICommentRepository commentRepository)
public PostAppService(IPostRepository postRepository, ITagRepository tagRepository, IPostTagRepository postTagRepository, ICommentRepository commentRepository, IBlogUserLookupService userLookupService)
{
UserLookupService = userLookupService;
_postRepository = postRepository;
_tagRepository = tagRepository;
_postTagRepository = postTagRepository;
@ -44,6 +49,13 @@ namespace Volo.Blogging.Posts
postDto.Tags = await GetTagsOfPost(postDto.Id);
postDto.CommentCount = await _commentRepository.GetCommentCountOfPostAsync(postDto.Id);
if (postDto.CreatorId.HasValue)
{
var creatorUser = await UserLookupService.FindByIdAsync(postDto.CreatorId.Value);
//TODO: Check if creatorUser is null!
Logger.LogWarning($"Creator of post {postDto.Id} is {creatorUser.UserName}");
}
}
if (!tagName.IsNullOrWhiteSpace())

1
modules/blogging/src/Volo.Blogging.Domain/Volo.Blogging.Domain.csproj

@ -11,6 +11,7 @@
<ItemGroup>
<ProjectReference Include="..\Volo.Blogging.Domain.Shared\Volo.Blogging.Domain.Shared.csproj" />
<ProjectReference Include="..\..\..\users\src\Volo.Abp.Users.Domain\Volo.Abp.Users.Domain.csproj" />
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.Ddd.Domain\Volo.Abp.Ddd.Domain.csproj" />
</ItemGroup>

6
modules/blogging/src/Volo.Blogging.Domain/Volo/Blogging/Blogs/Blog.cs

@ -33,5 +33,11 @@ namespace Volo.Blogging.Blogs
Name = Check.NotNullOrWhiteSpace(name, nameof(name));
return this;
}
public virtual Blog SetShortName(string shortName)
{
ShortName = Check.NotNullOrWhiteSpace(shortName, nameof(shortName));
return this;
}
}
}

5
modules/blogging/src/Volo.Blogging.Domain/Volo/Blogging/Blogs/IBlogRepository.cs

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
@ -7,5 +8,9 @@ namespace Volo.Blogging.Blogs
public interface IBlogRepository : IBasicRepository<Blog, Guid>
{
Task<Blog> FindByShortNameAsync(string shortName);
Task<List<Blog>> GetListAsync(string sorting, int maxResultCount, int skipCount);
Task<int> GetTotalBlogCount();
}
}

43
modules/blogging/src/Volo.Blogging.Domain/Volo/Blogging/Users/BlogUser.cs

@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using Volo.Abp.Data;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Users;
namespace Volo.Blogging.Users
{
public class BlogUser : AggregateRoot<Guid>, IUser, IHasExtraProperties
{
public virtual Guid? TenantId { get; protected set; }
public virtual string UserName { get; protected set; }
public virtual string Email { get; protected set; }
public virtual bool EmailConfirmed { get; protected set; }
public virtual string PhoneNumber { get; protected set; }
public virtual bool PhoneNumberConfirmed { get; protected set; }
public virtual Dictionary<string, object> ExtraProperties { get; protected set; }
protected BlogUser()
{
ExtraProperties = new Dictionary<string, object>();
}
public BlogUser(IUserData user)
{
Id = user.Id;
Email = user.Email;
EmailConfirmed = user.EmailConfirmed;
PhoneNumber = user.PhoneNumber;
PhoneNumberConfirmed = user.PhoneNumberConfirmed;
UserName = user.UserName;
TenantId = user.TenantId;
ExtraProperties = new Dictionary<string, object>();
}
}
}

22
modules/blogging/src/Volo.Blogging.Domain/Volo/Blogging/Users/BlogUserLookupService.cs

@ -0,0 +1,22 @@
using Volo.Abp.Uow;
using Volo.Abp.Users;
namespace Volo.Blogging.Users
{
public class BlogUserLookupService : UserLookupService<BlogUser, IBlogUserRepository>, IBlogUserLookupService
{
public BlogUserLookupService(
IBlogUserRepository userRepository,
IUnitOfWorkManager unitOfWorkManager)
: base(
userRepository,
unitOfWorkManager)
{
}
protected override BlogUser CreateUser(IUserData externalUser)
{
return new BlogUser(externalUser);
}
}
}

9
modules/blogging/src/Volo.Blogging.Domain/Volo/Blogging/Users/IBlogUserLookupService.cs

@ -0,0 +1,9 @@
using Volo.Abp.Users;
namespace Volo.Blogging.Users
{
public interface IBlogUserLookupService : IUserLookupService<BlogUser>
{
}
}

14
modules/blogging/src/Volo.Blogging.Domain/Volo/Blogging/Users/IBlogUserRepository.cs

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Users;
namespace Volo.Blogging.Users
{
public interface IBlogUserRepository : IBasicRepository<BlogUser, Guid>, IUserRepository<BlogUser>
{
Task<List<BlogUser>> GetUsersAsync(int maxCount, string filter, CancellationToken cancellationToken = default);
}
}

1
modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo.Blogging.EntityFrameworkCore.csproj

@ -12,6 +12,7 @@
<ItemGroup>
<ProjectReference Include="..\Volo.Blogging.Domain\Volo.Blogging.Domain.csproj" />
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.EntityFrameworkCore\Volo.Abp.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\..\users\src\Volo.Abp.Users.EntityFrameworkCore\Volo.Abp.Users.EntityFrameworkCore.csproj" />
</ItemGroup>
</Project>

17
modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/Blogs/EfCoreBlogRepository.cs

@ -1,4 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
@ -19,5 +22,19 @@ namespace Volo.Blogging.Blogs
{
return await DbSet.FirstOrDefaultAsync(p => p.ShortName == shortName);
}
public async Task<List<Blog>> GetListAsync(string sorting, int maxResultCount, int skipCount)
{
var auditLogs = await DbSet.OrderBy(sorting ?? "creationTime desc")
.PageBy(skipCount, maxResultCount)
.ToListAsync();
return auditLogs;
}
public async Task<int> GetTotalBlogCount()
{
return await DbSet.CountAsync();
}
}
}

3
modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/EntityFrameworkCore/BloggingDbContext.cs

@ -5,6 +5,7 @@ using Volo.Blogging.Blogs;
using Volo.Blogging.Comments;
using Volo.Blogging.Posts;
using Volo.Blogging.Tagging;
using Volo.Blogging.Users;
namespace Volo.Blogging.EntityFrameworkCore
{
@ -14,6 +15,8 @@ namespace Volo.Blogging.EntityFrameworkCore
public static string TablePrefix { get; set; } = BloggingConsts.DefaultDbTablePrefix;
public static string Schema { get; set; } = BloggingConsts.DefaultDbSchema;
public DbSet<BlogUser> Users { get; set; }
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }

10
modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/EntityFrameworkCore/BloggingDbContextModelBuilderExtensions.cs

@ -3,10 +3,12 @@ using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore;
using Volo.Abp;
using Volo.Abp.EntityFrameworkCore.Modeling;
using Volo.Abp.Users.EntityFrameworkCore;
using Volo.Blogging.Blogs;
using Volo.Blogging.Comments;
using Volo.Blogging.Posts;
using Volo.Blogging.Tagging;
using Volo.Blogging.Users;
namespace Volo.Blogging.EntityFrameworkCore
{
@ -21,6 +23,14 @@ namespace Volo.Blogging.EntityFrameworkCore
var options = new BloggingModelBuilderConfigurationOptions();
optionsAction?.Invoke(options);
builder.Entity<BlogUser>(b =>
{
b.ToTable(options.TablePrefix + "Users", options.Schema);
b.ConfigureAbpUser(options);
b.ConfigureExtraProperties();
});
builder.Entity<Blog>(b =>
{
b.ToTable(options.TablePrefix + "Blogs", options.Schema);

3
modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/EntityFrameworkCore/IBloggingDbContext.cs

@ -5,12 +5,15 @@ using Volo.Blogging.Blogs;
using Volo.Blogging.Comments;
using Volo.Blogging.Posts;
using Volo.Blogging.Tagging;
using Volo.Blogging.Users;
namespace Volo.Blogging.EntityFrameworkCore
{
[ConnectionStringName("Blogging")]
public interface IBloggingDbContext : IEfCoreDbContext
{
DbSet<BlogUser> Users { get; }
DbSet<Blog> Blogs { get; set; }
DbSet<Post> Posts { get; set; }

27
modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/Users/EfCoreQaUserRepository.cs

@ -0,0 +1,27 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Users.EntityFrameworkCore;
using Volo.Blogging.EntityFrameworkCore;
namespace Volo.Blogging.Users
{
public class EfCoreBlogUserRepository : EfCoreUserRepositoryBase<IBloggingDbContext, BlogUser>, IBlogUserRepository
{
public EfCoreBlogUserRepository(IDbContextProvider<IBloggingDbContext> dbContextProvider)
: base(dbContextProvider)
{
}
public async Task<List<BlogUser>> GetUsersAsync(int maxCount, string filter, CancellationToken cancellationToken = default)
{
return await DbSet
.WhereIf( !string.IsNullOrWhiteSpace( filter), x=>x.UserName.Contains(filter))
.Take(maxCount).ToListAsync(cancellationToken);
}
}
}

1
modules/blogging/src/Volo.Blogging.HttpApi.Client/Volo.Blogging.HttpApi.Client.csproj

@ -11,6 +11,7 @@
<ItemGroup>
<ProjectReference Include="..\Volo.Blogging.Application.Contracts\Volo.Blogging.Application.Contracts.csproj" />
<ProjectReference Include="..\..\..\..\..\abp\framework\src\Volo.Abp.Http.Client\Volo.Abp.Http.Client.csproj" />
</ItemGroup>
</Project>

10
modules/blogging/src/Volo.Blogging.HttpApi.Client/Volo/Blogging/BloggingHttpApiClientModule.cs

@ -1,12 +1,20 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Http.Client;
using Volo.Abp.Modularity;
namespace Volo.Blogging
{
[DependsOn(
typeof(BloggingApplicationContractsModule))]
typeof(BloggingApplicationContractsModule),
typeof(AbpHttpClientModule))]
public class BloggingHttpApiClientModule : AbpModule
{
public const string RemoteServiceName = "Blogging";
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddHttpClientProxies(typeof(BloggingApplicationContractsModule).Assembly, RemoteServiceName);
}
}
}

1
modules/blogging/src/Volo.Blogging.HttpApi/Volo.Blogging.HttpApi.csproj

@ -11,6 +11,7 @@
<ItemGroup>
<ProjectReference Include="..\Volo.Blogging.Application.Contracts\Volo.Blogging.Application.Contracts.csproj" />
<ProjectReference Include="..\..\..\..\..\abp\framework\src\Volo.Abp.AspNetCore.Mvc\Volo.Abp.AspNetCore.Mvc.csproj" />
</ItemGroup>
</Project>

5
modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/BloggingHttpApiModule.cs

@ -1,10 +1,11 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.Modularity;
namespace Volo.Blogging
{
[DependsOn(
typeof(BloggingApplicationContractsModule))]
typeof(BloggingApplicationContractsModule),
typeof(AbpAspNetCoreMvcModule))]
public class BloggingHttpApiModule : AbpModule
{

77
modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/BlogsController.cs

@ -0,0 +1,77 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.Auditing;
using Volo.Blogging.Blogs;
using Volo.Blogging.Blogs.Dtos;
namespace Volo.Blogging
{
[RemoteService]
[Area("blogging")]
[Controller]
[ControllerName("Blogs")]
[Route("api/blogging/blogs")]
[DisableAuditing]
public class BlogsController : AbpController, IBlogAppService
{
private readonly IBlogAppService _blogAppService;
public BlogsController(IBlogAppService blogAppService)
{
_blogAppService = blogAppService;
}
[HttpGet]
[Route("")]
public async Task<PagedResultDto<BlogDto>> GetListPagedAsync(PagedAndSortedResultRequestDto input)
{
return await _blogAppService.GetListPagedAsync(input);
}
[HttpGet]
[Route("/all")]
public async Task<ListResultDto<BlogDto>> GetListAsync()
{
return await _blogAppService.GetListAsync();
}
[HttpGet]
[Route("{shortName}")]
public async Task<BlogDto> GetByShortNameAsync(string shortName)
{
return await _blogAppService.GetByShortNameAsync(shortName);
}
[HttpGet]
[Route("{id}")]
public async Task<BlogDto> GetAsync(Guid id)
{
return await _blogAppService.GetAsync(id);
}
[HttpPost]
public async Task<BlogDto> Create(CreateBlogDto input)
{
return await _blogAppService.Create(input);
}
[HttpPut]
[Route("{id}")]
public async Task<BlogDto> Update(Guid id, UpdateBlogDto input)
{
throw new NotImplementedException();
}
[HttpDelete]
public async Task Delete(Guid id)
{
await _blogAppService.Delete(id);
}
}
}

5
modules/blogging/src/Volo.Blogging.Web/AbpBloggingWebAutoMapperProfile.cs

@ -1,8 +1,11 @@
using AutoMapper;
using Volo.Abp.AutoMapper;
using Volo.Blogging.Blogs;
using Volo.Blogging.Blogs.Dtos;
using Volo.Blogging.Pages.Admin.Blogs;
using Volo.Blogging.Pages.Blog.Posts;
using Volo.Blogging.Posts;
using EditModel = Volo.Blogging.Pages.Admin.Blogs.EditModel;
using IndexModel = Volo.Blogging.Pages.Blog.IndexModel;
namespace Volo.Blogging
@ -14,6 +17,8 @@ namespace Volo.Blogging
CreateMap<PostWithDetailsDto, EditPostViewModel>().Ignore(x=>x.Tags);
CreateMap<NewModel.CreatePostViewModel, CreatePostDto>();
CreateMap<IndexModel.BlogIndexViewModel, CreateBlogDto>();
CreateMap<CreateModel.BlogCreateModalView, CreateBlogDto>();
CreateMap<BlogDto, EditModel.BlogEditViewModel>();
}
}
}

7
modules/blogging/src/Volo.Blogging.Web/BloggingMenuContributor.cs

@ -27,7 +27,14 @@ namespace Volo.Blogging
var rootMenuItem = new ApplicationMenuItem("Blogs", l["Menu:Blogs"], "/Blog");
context.Menu.AddItem(rootMenuItem);
var managementRootMenuItem = new ApplicationMenuItem("BlogManagement", l["Menu:BlogManagement"]);
managementRootMenuItem.AddItem(new ApplicationMenuItem("Blogs", l["Menu:Blogs"], "/Admin/Blogs"));
context.Menu.AddItem(managementRootMenuItem);
}
}
}
}

8
modules/blogging/src/Volo.Blogging.Web/BloggingWebModule.cs

@ -2,6 +2,7 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AspNetCore.Mvc.Localization;
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap;
using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
using Volo.Abp.AutoMapper;
using Volo.Abp.Localization;
using Volo.Abp.Localization.Resources.AbpValidation;
@ -15,8 +16,9 @@ namespace Volo.Blogging
{
[DependsOn(
typeof(BloggingHttpApiModule),
typeof(AbpAutoMapperModule),
typeof(AbpAspNetCoreMvcUiBootstrapModule)
typeof(AbpAspNetCoreMvcUiBootstrapModule),
typeof(AbpAspNetCoreMvcUiBundlingModule),
typeof(AbpAutoMapperModule)
)]
public class BloggingWebModule : AbpModule
{
@ -37,7 +39,7 @@ namespace Volo.Blogging
Configure<VirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<BloggingWebModule>("Volo.Blogging");
options.FileSets.AddEmbedded<BloggingWebModule>("Volo.Blogging.Web");
});
Configure<AbpLocalizationOptions>(options =>

1
modules/blogging/src/Volo.Blogging.Web/Localization/Resources/Blogging/Web/en.json

@ -2,6 +2,7 @@
"culture": "en",
"texts": {
"Menu:Blogs": "Blog",
"Menu:BlogManagement": "Blog Management",
"Title": "Title",
"ContinueReading": "Continue Reading",
"DaysAgo": "days ago",

1
modules/blogging/src/Volo.Blogging.Web/Localization/Resources/Blogging/Web/tr.json

@ -3,6 +3,7 @@
"texts": {
"Menu:Blogs": "Blog",
"Title": "Başlık",
"Menu:BlogManagement": "Blog Yönetimi",
"ContinueReading": "Devamı...",
"DaysAgo": "Gün Önce",
"YearsAgo": "yıl önce",

20
modules/blogging/src/Volo.Blogging.Web/Pages/Admin/Blogs/Create.cshtml

@ -0,0 +1,20 @@
@page
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal
@using Volo.Blogging.Pages.Blog
@inherits BloggingPage
@model Volo.Blogging.Pages.Admin.Blogs.CreateModel
@{
Layout = null;
}
<abp-dynamic-form submit-button="false" abp-model="Blog" asp-page="/Admin/Blogs/Create">
<abp-modal size="@(AbpModalSize.Large)">
<abp-modal-header title="@L["Create"].Value"></abp-modal-header>
<abp-modal-body>
<abp-form-content/>
</abp-modal-body>
<abp-modal-footer buttons="@(AbpModalButtons.Cancel|AbpModalButtons.Save)">
</abp-modal-footer>
</abp-modal>
</abp-dynamic-form>

50
modules/blogging/src/Volo.Blogging.Web/Pages/Admin/Blogs/Create.cshtml.cs

@ -0,0 +1,50 @@
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form;
using Volo.Abp.AspNetCore.Mvc.UI.RazorPages;
using Volo.Blogging.Blogs;
using Volo.Blogging.Blogs.Dtos;
namespace Volo.Blogging.Pages.Admin.Blogs
{
public class CreateModel : AbpPageModel
{
private readonly IBlogAppService _blogAppService;
[BindProperty]
public BlogCreateModalView Blog { get; set; } = new BlogCreateModalView();
public CreateModel(IBlogAppService blogAppService)
{
_blogAppService = blogAppService;
}
public void OnGet()
{
}
public async void OnPostAsync()
{
var language = ObjectMapper.Map<BlogCreateModalView, CreateBlogDto>(Blog);
await _blogAppService.Create(language);
}
public class BlogCreateModalView
{
[Required]
[StringLength(BlogConsts.MaxNameLength)]
public string Name { get; set; }
[Required]
[StringLength(BlogConsts.MaxShortNameLength)]
public string ShortName { get; set; }
[StringLength(BlogConsts.MaxDescriptionLength)]
public string Description { get; set; }
}
}
}

20
modules/blogging/src/Volo.Blogging.Web/Pages/Admin/Blogs/Edit.cshtml

@ -0,0 +1,20 @@
@page
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal
@using Volo.Blogging.Pages.Blog
@inherits BloggingPage
@model Volo.Blogging.Pages.Admin.Blogs.EditModel
@{
Layout = null;
}
<abp-dynamic-form submit-button="false" abp-model="Blog" asp-page="/Admin/Blogs/Edit">
<abp-modal size="@(AbpModalSize.Large)">
<abp-modal-header title="@L["Create"].Value"></abp-modal-header>
<abp-modal-body>
<abp-form-content />
</abp-modal-body>
<abp-modal-footer buttons="@(AbpModalButtons.Cancel|AbpModalButtons.Save)">
</abp-modal-footer>
</abp-modal>
</abp-dynamic-form>

65
modules/blogging/src/Volo.Blogging.Web/Pages/Admin/Blogs/Edit.cshtml.cs

@ -0,0 +1,65 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc.UI.RazorPages;
using Volo.Blogging.Blogs;
using Volo.Blogging.Blogs.Dtos;
using Volo.Blogging.Posts;
namespace Volo.Blogging.Pages.Admin.Blogs
{
public class EditModel : AbpPageModel
{
private readonly IBlogAppService _blogAppService;
[BindProperty(SupportsGet = true)]
public Guid BlogId { get; set; }
[BindProperty]
public BlogEditViewModel Blog { get; set; } = new BlogEditViewModel();
public EditModel(IBlogAppService blogAppService)
{
_blogAppService = blogAppService;
}
public async Task OnGet()
{
var blog = await _blogAppService.GetAsync(BlogId);
Blog = ObjectMapper.Map<BlogDto, BlogEditViewModel>(blog);
}
public async Task OnPost()
{
await _blogAppService.Update(Blog.Id, new UpdateBlogDto()
{
Name = Blog.Name,
ShortName = Blog.ShortName,
Description = Blog.Description
});
}
public class BlogEditViewModel
{
[HiddenInput]
[Required]
public Guid Id { get; set; }
[Required]
[StringLength(BlogConsts.MaxNameLength)]
public string Name { get; set; }
[Required]
[StringLength(BlogConsts.MaxShortNameLength)]
public string ShortName { get; set; }
[StringLength(BlogConsts.MaxDescriptionLength)]
public string Description { get; set; }
}
}
}

44
modules/blogging/src/Volo.Blogging.Web/Pages/Admin/Blogs/Index.cshtml

@ -0,0 +1,44 @@
@page
@using Microsoft.AspNetCore.Authorization
@using Volo.Blogging
@using Volo.Blogging.Pages.Blog
@inherits BloggingPage
@model IndexModel
@inject IAuthorizationService Authorization
@{
ViewBag.PageTitle = "Blogs";
}
@section scripts {
<abp-script src="/Pages/Admin/Blogs/index.js" />
<abp-script src="/Pages/Admin/Blogs/create.js" />
}
<abp-card>
<abp-card-header>
<abp-row>
<abp-column size-md="_6">
<h2>@L["Blogs"]</h2>
</abp-column>
<abp-column size-md="_6" class="text-right">
@if (await Authorization.IsGrantedAsync(BloggingPermissions.Blogs.Create))
{
<abp-button icon="plus" text="@L["CreateNewBlog"].Value" button-type="Primary" id="CreateNewBlogButtonId"></abp-button>
}
</abp-column>
</abp-row>
</abp-card-header>
<abp-card-body>
<abp-table striped-rows="true" id="BlogsTable" class="nowrap">
<thead>
<tr>
<th>@L["Actions"]</th>
<th>@L["Name"]</th>
<th>@L["ShortName"]</th>
<th>@L["CreationTime"]</th>
<th>@L["Description"]</th>
</tr>
</thead>
</abp-table>
</abp-card-body>
</abp-card>

12
modules/blogging/src/Volo.Blogging.Web/Pages/Admin/Blogs/Index.cshtml.cs

@ -0,0 +1,12 @@
using Volo.Abp.AspNetCore.Mvc.UI.RazorPages;
namespace Volo.Blogging.Pages.Admin.Blogs
{
public class IndexModel : AbpPageModel
{
public void OnGet()
{
}
}
}

14
modules/blogging/src/Volo.Blogging.Web/Pages/Admin/Blogs/create.js

@ -0,0 +1,14 @@
var abp = abp || {};
$(function () {
abp.modals.blogCreate = function () {
var initModal = function (publicApi, args) {
var $form = publicApi.getForm();
};
return {
initModal: initModal
}
};
});

14
modules/blogging/src/Volo.Blogging.Web/Pages/Admin/Blogs/edit.js

@ -0,0 +1,14 @@
var abp = abp || {};
$(function () {
abp.modals.blogEdit = function () {
var initModal = function (publicApi, args) {
var $form = publicApi.getForm();
};
return {
initModal: initModal
}
};
});

85
modules/blogging/src/Volo.Blogging.Web/Pages/Admin/Blogs/index.js

@ -0,0 +1,85 @@
$(function () {
var _createModal = new abp.ModalManager(abp.appPath + 'Admin/Blogs/Create');
var _editModal = new abp.ModalManager(abp.appPath + 'Admin/Blogs/Edit');
var _dataTable = $('#BlogsTable').DataTable(abp.libs.datatables.normalizeConfiguration({
processing: true,
serverSide: true,
paging: true,
searching: false,
autoWidth: false,
scrollX: true,
scrollCollapse: true,
order: [[3, "desc"]],
ajax: abp.libs.datatables.createAjax(volo.blogging.blogs.getListPaged),
columnDefs: [
{
targets: 0, //optional
rowAction: {
items:
[
{
text: 'Edit',
visible: function () {
return true; //TODO: Check permission
},
action: function (data) {
_editModal.open({
blogId: data.record.id
});
}
},
{
text: 'Delete',
visible: function () {
return true; //TODO: Check permission
},
confirmMessage: function (data) { return 'Todo: fill this message' },
action: function (data) {
volo.blogging.blogs
.delete(data.record.id)
.then(function () {
_dataTable.ajax.reload();
});
}
}
]
}
},
{
target: 1,
data: "name"
},
{
target: 2,
data: "shortName"
},
{
target: 3,
data: "creationTime",
render: function (date) {
return date;
}
},
{
target: 4,
data: "description"
}
]
}));
$("#CreateNewBlogButtonId").click(function () {
_createModal.open();
});
_createModal.onClose(function () {
_dataTable.ajax.reload();
});
_editModal.onResult(function () {
_dataTable.ajax.reload();
});
});

1
modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Index.cshtml.cs

@ -4,6 +4,7 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc.UI.RazorPages;
using Volo.Blogging.Blogs;
using Volo.Blogging.Blogs.Dtos;
namespace Volo.Blogging.Pages.Blog
{

385
modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Posts/Detail.cshtml

@ -19,24 +19,19 @@
<abp-style src="/Pages/Blog/Shared/Styles/blog.css" />
</abp-style-bundle>
}
<div class="vs-blog">
<div class="row mb-5">
<div class="col-md-12 mx-auto">
<section class="hero-section">
<div class="hero-articles">
<div class="img-container" style="min-height: 480px; background: url(@Model.Post.CoverImage) center center no-repeat; background-size: cover; ">
</div>
<div class="hero-content">
<p class="tags">
@foreach (var tag in Model.Post.Tags)
{
<a asp-page="/Blog/Posts/Index" asp-route-blogShortName="@Model.BlogShortName" asp-route-tagName="@tag.Name" class="tag">@tag.Name</a>
}
</p>
<h1>
<a href="#">@Model.Post.Title</a>
<div class="vs-blog">
<div class="vs-blog-header">
<div class="vs-blog-title">
<div class="row">
<div class="col">
<h1 class="my-0 display-inline-block">
@L["Volosoft"]
<small class="text-muted">
BLOG
</small>
</h1>
</div>
<<<<<<< HEAD
<div class="article-owner">
<div class="article-infos">
<div class="user-card">
@ -56,7 +51,7 @@
</a>
@if (await Authorization.IsGrantedAsync(BloggingPermissions.Posts.Update))
@if (await Authorization.IsGrantedAsync(BloggingPermissions.Posts.Update) || (CurrentUser.Id == Model.Post.CreatorId))
{
<span class="seperator">|</span>
<a asp-page="./Edit" asp-route-postId="@Model.Post.Id" asp-route-blogShortName="@Model.BlogShortName">
@ -69,193 +64,259 @@
<div class="user-link-icons">
<a class="add-bookmark" href="#">
<i class="fa fa-bookmark"></i>
=======
<div class="col-sm-4 text-right">
<br />
<a href="#">
<i class="fa fa fa-angle-left"></i> Blog
</a>
<span class="vs-seperator">|</span>
<a href="#">
<i class="fa fa-twitter"></i>
</a>
<span class="vs-seperator">|</span>
<a href="#">
<i class="fa fa-github"></i>
>>>>>>> 5023d9202b64c4367e1234ad5e5f7acb76c592e3
</a>
<a class="share-article" href="#">
<i class="fa fa-share-alt"></i>
<span class="vs-seperator">|</span>
<a href="#">
<i class="fa fa-stack-overflow"></i>
</a>
</div>
</div>
</section>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12 mx-auto">
<section class="hero-section">
<div class="hero-articles">
<div class="img-container" style="min-height: 480px; background: url(@Model.Post.CoverImage) center center no-repeat; background-size: cover; ">
</div>
<div class="hero-content">
<p class="tags">
@foreach (var tag in Model.Post.Tags)
{
<a asp-page="/Blog/Posts/Index" asp-route-blogShortName="@Model.BlogShortName" asp-route-tagName="@tag.Name" class="tag">@tag.Name</a>
}
</p>
<h1>
<a href="#">@Model.Post.Title</a>
</h1>
</div>
<div class="article-owner">
<div class="article-infos">
<div class="user-card">
<a href="#">
<img src="https://placeimg.com/60/60/people" class="article-avatar">
</a>
<a href="#">
<strong> Halil İbrahim Kalkan</strong>, @ConvertDatetimeToTimeAgo(Model.Post.CreationTime)
</a>
<span class="vs-seperator">|</span>
<a href="#">
<i class="fa fa-eye"></i> @Model.Post.ReadCount @L["Read"]
</a>
<span class="vs-seperator">|</span>
<a href="#">
<i class="fa fa-comment"></i> @Model.CommentCount @L["Comment"]
</a>
<div class="row">
<div class="col-md-8 mx-auto">
<section class="post-content">
<p>@Html.Raw(Model.FormattedContent)</p>
</section>
@if (await Authorization.IsGrantedAsync(BloggingPermissions.Posts.Update))
{
<span class="seperator">|</span>
<a asp-page="./Edit" asp-route-postId="@Model.Post.Id" asp-route-blogShortName="@Model.BlogShortName">
<i class="fa fa-pencil"></i> @L["Edit"]
</a>
}
</div>
</div>
</div>
</div>
</section>
</div>
</div>
</div>
<div class="row">
<div class="col-md-8 mx-auto">
<div class="tags">
<h5>@L["TagsInThisArticle"]</h5>
@foreach (var tag in Model.Post.Tags)
{
<a asp-page="/Blog/Posts/Index" asp-route-blogShortName="@Model.BlogShortName" asp-route-tagName="@tag.Name" class="tag">@tag.Name</a>
}
<div class="row">
<div class="col-md-8 mx-auto">
<section class="post-content">
<p>@Html.Raw(Model.FormattedContent)</p>
</section>
</div>
<div class="comment-form mt-4">
<div class="clearfix bg-light p-4">
<h3 class="mt-0">@L["LeaveComment"]</h3>
<div>
<form method="post">
<input name="postId" value="@Model.Post.Id" hidden />
<input name="repliedCommentId" id="repliedCommentId" hidden />
<div class="form-group">
<textarea class="form-control no-border" name="text" id="textBoxId" rows="4"></textarea>
</div>
<abp-button button-type="Primary" class="btn-rounded float-right" type="submit" text="@L["Submit"].Value" />
</form>
</div>
<div class="row">
<div class="col-md-8 mx-auto">
<div class="tags">
<h5>@L["TagsInThisArticle"]</h5>
@foreach (var tag in Model.Post.Tags)
{
<a asp-page="/Blog/Posts/Index" asp-route-blogShortName="@Model.BlogShortName" asp-route-tagName="@tag.Name" class="tag">@tag.Name</a>
}
</div>
<div class="comment-form mt-4">
<div class="vs-blog-title mb-0">
<h3>@L["LeaveComment"]</h3>
</div>
<div class="clearfix bg-light p-4">
<div>
<form method="post">
<input name="postId" value="@Model.Post.Id" hidden />
<input name="repliedCommentId" id="repliedCommentId" hidden />
<div class="form-group">
<textarea class="form-control no-border" name="text" id="textBoxId" rows="4"></textarea>
</div>
<abp-button button-type="Primary" class="btn-rounded float-right" type="submit" text="@L["Submit"].Value" />
</form>
</div>
</div>
</div>
</div>
<div class="comment-area">
<div class="comment-area">
@foreach (var commentWithRepliesDto in Model.CommentsWithReplies)
{
<div class="media">
<img class="d-flex mr-3 rounded-circle comment-avatar" src="https://placeimg.com/120/120/people" alt="">
<div class="media-body">
<h5 class="comment-owner">
Armağan Ünlü
<span class="float-right">@ConvertDatetimeToTimeAgo(commentWithRepliesDto.Comment.CreationTime)</span>
</h5>
<p id="@commentWithRepliesDto.Comment.Id">
@commentWithRepliesDto.Comment.Text
</p>
<div class="comment-buttons">
@foreach (var commentWithRepliesDto in Model.CommentsWithReplies)
{
<div class="media">
<img class="d-flex mr-3 rounded-circle comment-avatar" src="https://placeimg.com/120/120/people" alt="">
<div class="media-body">
<h5 class="comment-owner">
Armağan Ünlü
<span class="float-right">@ConvertDatetimeToTimeAgo(commentWithRepliesDto.Comment.CreationTime)</span>
</h5>
<p id="@commentWithRepliesDto.Comment.Id">
@commentWithRepliesDto.Comment.Text
</p>
<div class="comment-buttons font-75 bg-light">
<a href="#" class="tag replyLink" data-relpyid="@commentWithRepliesDto.Comment.Id">
<i class="fa fa-reply" aria-hidden="true"></i> @L["Reply"]
</a>
@if (await Authorization.IsGrantedAsync(BloggingPermissions.Comments.Delete))
{
<span class="seperator">|</span>
<a href="#" class="tag deleteLink" data-deleteid="@commentWithRepliesDto.Comment.Id">
<i class="fa fa-trash" aria-hidden="true"></i> @L["Delete"]
<a href="#" class="tag replyLink" data-relpyid="@commentWithRepliesDto.Comment.Id">
<i class="fa fa-reply" aria-hidden="true"></i> @L["Reply"]
</a>
}
@if (await Authorization.IsGrantedAsync(BloggingPermissions.Comments.Update) || (CurrentUser.Id == commentWithRepliesDto.Comment.CreatorId))
{
<span class="seperator">|</span>
<a href="#" class="tag updateLink" data-updateid="@commentWithRepliesDto.Comment.Id">
<i class="fa fa-pencil" aria-hidden="true"></i> @L["Edit"]
</a>
}
</div>
<div class="comment-form mt-4 replyForm">
<div class="clearfix bg-light p-4">
<h3 class="mt-0">@L["ReplyTo"] Armağan Ünlü</h3>
<div>
<form method="post">
<input name="postId" value="@Model.Post.Id" hidden />
<input name="repliedCommentId" value="@commentWithRepliesDto.Comment.Id" hidden />
@if (await Authorization.IsGrantedAsync(BloggingPermissions.Comments.Delete))
{
<span class="seperator">|</span>
<a href="#" class="tag deleteLink" data-deleteid="@commentWithRepliesDto.Comment.Id">
<i class="fa fa-trash" aria-hidden="true"></i> @L["Delete"]
</a>
}
<div class="form-group">
<textarea class="form-control no-border" name="text" id="textBoxId" rows="4"></textarea>
</div>
<abp-button button-type="Primary" class="btn-rounded float-right" type="submit" text="@L["Comment"].Value" />
</form>
</div>
@if (await Authorization.IsGrantedAsync(BloggingPermissions.Comments.Update) || (CurrentUser.Id == commentWithRepliesDto.Comment.CreatorId))
{
<span class="seperator">|</span>
<a href="#" class="tag updateLink" data-updateid="@commentWithRepliesDto.Comment.Id">
<i class="fa fa-pencil" aria-hidden="true"></i> @L["Edit"]
</a>
}
</div>
</div>
@if (await Authorization.IsGrantedAsync(BloggingPermissions.Comments.Update) || (CurrentUser.Id == commentWithRepliesDto.Comment.CreatorId))
{
<div class="comment-form mt-4 editForm">
<div class="comment-form mt-4 replyForm">
<div class="clearfix bg-light p-4">
<h3 class="mt-0">@L["ReplyTo"] Armağan Ünlü</h3>
<div>
<form class="editFormClass">
<input name="commentId" value="@commentWithRepliesDto.Comment.Id" hidden/>
<form method="post">
<input name="postId" value="@Model.Post.Id" hidden />
<input name="repliedCommentId" value="@commentWithRepliesDto.Comment.Id" hidden />
<div class="form-group">
<textarea class="form-control no-border" name="text" id="textBoxId" rows="4">@commentWithRepliesDto.Comment.Text</textarea>
<textarea class="form-control no-border" name="text" id="textBoxId" rows="4"></textarea>
</div>
<abp-button button-type="Primary" class="btn-rounded float-right" type="submit" text="@L["Submit"].Value"/>
<abp-button button-type="Primary" class="btn-rounded float-right" type="submit" text="@L["Comment"].Value" />
</form>
</div>
</div>
</div>
}
@foreach (var reply in commentWithRepliesDto.Replies)
{
<div class="media">
<img class="d-flex mr-3 rounded-circle answer-avatar" src="https://placeimg.com/120/120/people?t=1535457179534" alt="">
<div class="media-body">
<h5 class="comment-owner">
Zlatan Ibrahimovic
<span class="float-right">@ConvertDatetimeToTimeAgo(reply.CreationTime)</span>
</h5>
<p id="@reply.Id">
@reply.Text
</p>
<div class="comment-buttons">
<a href="#" class="tag" data-relpyid="@commentWithRepliesDto.Comment.Id">
<i class="fa fa-reply" aria-hidden="true"></i> @L["Reply"]
</a>
@if (await Authorization.IsGrantedAsync(BloggingPermissions.Comments.Update) || (CurrentUser.Id == commentWithRepliesDto.Comment.CreatorId))
{
<div class="comment-form mt-4 editForm">
<div class="clearfix bg-light p-4">
<div>
<form class="editFormClass">
<input name="commentId" value="@commentWithRepliesDto.Comment.Id" hidden />
<div class="form-group">
<textarea class="form-control no-border" name="text" id="textBoxId" rows="4">@commentWithRepliesDto.Comment.Text</textarea>
</div>
<abp-button button-type="Primary" class="btn-rounded float-right" type="submit" text="@L["Submit"].Value" />
</form>
</div>
</div>
</div>
}
@if (await Authorization.IsGrantedAsync(BloggingPermissions.Comments.Delete) || (CurrentUser.Id == commentWithRepliesDto.Comment.CreatorId))
{
<span class="seperator">|</span>
<a href="#" class="tag" data-deleteid="@reply.Id">
<i class="fa fa-trash" aria-hidden="true"></i> @L["Delete"]
@foreach (var reply in commentWithRepliesDto.Replies)
{
<div class="media">
<img class="d-flex mr-3 rounded-circle answer-avatar" src="https://placeimg.com/120/120/people?t=1535457179534" alt="">
<div class="media-body">
<h5 class="comment-owner">
Zlatan Ibrahimovic
<span class="float-right">@ConvertDatetimeToTimeAgo(reply.CreationTime)</span>
</h5>
<p id="@reply.Id">
@reply.Text
</p>
<div class="comment-buttons font-75 bg-light">
<a href="#" class="tag" data-relpyid="@commentWithRepliesDto.Comment.Id">
<i class="fa fa-reply" aria-hidden="true"></i> @L["Reply"]
</a>
}
@if (await Authorization.IsGrantedAsync(BloggingPermissions.Comments.Update) || (CurrentUser.Id == commentWithRepliesDto.Comment.CreatorId))
{
<span class="seperator">|</span>
<a href="#" class="tag" data-updateid="@reply.Id">
<i class="fa fa-pencil" aria-hidden="true"></i> @L["Edit"]
</a>
}
</div>
@if (await Authorization.IsGrantedAsync(BloggingPermissions.Comments.Delete) || (CurrentUser.Id == commentWithRepliesDto.Comment.CreatorId))
{
<span class="seperator">|</span>
<a href="#" class="tag" data-deleteid="@reply.Id">
<i class="fa fa-trash" aria-hidden="true"></i> @L["Delete"]
</a>
}
<div class="comment-form mt-4 replyForm">
<div class="clearfix bg-light p-4">
<h3 class="mt-0">@L["ReplyTo"] Armağan Ünlü</h3>
<div>
<form method="post">
<input name="postId" value="@Model.Post.Id" hidden />
<input name="repliedCommentId" value="@commentWithRepliesDto.Comment.Id" hidden />
<div class="form-group">
<textarea class="form-control no-border" name="text" id="textBoxId" rows="4"></textarea>
</div>
<abp-button button-type="Primary" class="btn-rounded float-right" type="submit" text="@L["Submit"].Value" />
</form>
</div>
@if (await Authorization.IsGrantedAsync(BloggingPermissions.Comments.Update) || (CurrentUser.Id == commentWithRepliesDto.Comment.CreatorId))
{
<span class="seperator">|</span>
<a href="#" class="tag" data-updateid="@reply.Id">
<i class="fa fa-pencil" aria-hidden="true"></i> @L["Edit"]
</a>
}
</div>
</div>
@if (await Authorization.IsGrantedAsync(BloggingPermissions.Comments.Update) || (CurrentUser.Id == commentWithRepliesDto.Comment.CreatorId))
{
<div class="comment-form mt-4 editForm">
<div class="comment-form mt-4 replyForm">
<div class="clearfix bg-light p-4">
<h3 class="mt-0">@L["ReplyTo"] Armağan Ünlü</h3>
<div>
<form class="editFormClass">
<input name="commentId" value="@reply.Id" hidden/>
<form method="post">
<input name="postId" value="@Model.Post.Id" hidden />
<input name="repliedCommentId" value="@commentWithRepliesDto.Comment.Id" hidden />
<div class="form-group">
<textarea class="form-control no-border" name="text" id="textBoxId" rows="4">@reply.Text</textarea>
<textarea class="form-control no-border" name="text" id="textBoxId" rows="4"></textarea>
</div>
<abp-button button-type="Primary" class="btn-rounded float-right" type="submit" text="@L["Submit"].Value"/>
<abp-button button-type="Primary" class="btn-rounded float-right" type="submit" text="@L["Submit"].Value" />
</form>
</div>
</div>
</div>
}
@if (await Authorization.IsGrantedAsync(BloggingPermissions.Comments.Update) || (CurrentUser.Id == commentWithRepliesDto.Comment.CreatorId))
{
<div class="comment-form mt-4 editForm">
<div class="clearfix bg-light p-4">
<div>
<form class="editFormClass">
<input name="commentId" value="@reply.Id" hidden />
<div class="form-group">
<textarea class="form-control no-border" name="text" id="textBoxId" rows="4">@reply.Text</textarea>
</div>
<abp-button button-type="Primary" class="btn-rounded float-right" type="submit" text="@L["Submit"].Value" />
</form>
</div>
</div>
</div>
}
</div>
</div>
</div>
}
}
</div>
</div>
</div>
}
}
</div>
</div>
</div>
</div>
</div>

1
modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Posts/Detail.cshtml.cs

@ -7,6 +7,7 @@ using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Volo.Blogging.Blogs;
using Volo.Blogging.Blogs.Dtos;
using Volo.Blogging.Comments;
using Volo.Blogging.Comments.Dtos;
using Volo.Blogging.Posts;

289
modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Posts/Index.cshtml

@ -24,72 +24,96 @@
}
<div class="vs-blog">
<div class="container hero-container pb-5 bg-white">
<div class="vs-blog-header">
<div class="vs-blog-title">
<div class="row">
<div class="col">
<h1 class="my-0 display-inline-block">
@L["Volosoft"]
<small class="text-muted">
BLOG
</small>
</h1>
</div>
<div class="col-sm-4 text-right">
<br />
@if (await Authorization.IsGrantedAsync(BloggingPermissions.Posts.Create))
{
<a asp-page="./New" asp-route-blogShortName="@Model.BlogShortName">@L["CreateANewPost"]</a>
}
<span class="vs-seperator">|</span>
<a href="#">
<i class="fa fa-twitter"></i>
</a>
<span class="vs-seperator">|</span>
<a href="#">
<i class="fa fa-github"></i>
</a>
<span class="vs-seperator">|</span>
<a href="#">
<i class="fa fa-stack-overflow"></i>
</a>
</div>
</div>
</div>
</div>
<div class="pb-3">
<div class="row">
<div class="col-md-8">
<section class="hero-section">
<div class="owl-carousel owl-theme">
@for (var index = 0; index < Model.Posts.Count && index < 1; index++)
{
var post = Model.Posts[index];
<div class="hero-articles">
<div class="img-container">
<a asp-page="./Detail" asp-route-postUrl="@post.Url" asp-route-blogShortName="@Model.BlogShortName">
<img src="@post.CoverImage" class="hero-article-img">
</a>
</div>
<div class="hero-content">
<p class="tags">
@foreach (var tag in post.Tags)
{
<a asp-page="/Blog/Posts/Index" asp-route-blogShortName="@Model.BlogShortName" asp-route-tagName="@tag.Name" class="tag">@tag.Name</a>
}
</p>
<h2>
<a asp-page="./Detail" asp-route-postUrl="@post.Url" asp-route-blogShortName="@Model.BlogShortName">@post.Title</a>
</h2>
<p class="article-sum">
@(post.Content == null ? "" : (post.Content.Length > 150 ? post.Content.Substring(0, 150) + "..." : post.Content))
</p>
<a asp-page="./Detail" asp-route-postUrl="@post.Url" asp-route-blogShortName="@Model.BlogShortName" class="btn btn-primary btn-rounded">@L["ContinueReading"]</a>
@for (var index = 0; index < Model.Posts.Count && index < 3; index++)
{
var post = Model.Posts[index];
<div class="item">
<div class="hero-articles">
<div class="img-container">
<a asp-page="./Detail" asp-route-postUrl="@post.Url" asp-route-blogShortName="@Model.BlogShortName">
<img src="@post.CoverImage" class="hero-article-img">
</div>
<div class="article-owner">
<div class="article-infos">
<div class="user-card">
<a>
<img src="https://placeimg.com/120/120/people" class="article-avatar">
</a>
<a>
<strong>Armağan Ünlü</strong>, @ConvertDatetimeToTimeAgo(post.CreationTime)
</a>
<span class="vs-seperator">|</span>
<a>
<i class="fa fa-eye"></i> @post.ReadCount @L["Read"]
</a>
<span class="vs-seperator">|</span>
<a>
<i class="fa fa-comment"></i> @post.CommentCount @L["Comment"]
</a>
</div>
<div class="hero-content">
<p class="tags">
@foreach (var tag in post.Tags)
{
<a asp-page="/Blog/Posts/Index" asp-route-blogShortName="@Model.BlogShortName" asp-route-tagName="@tag.Name" class="tag">@tag.Name</a>
}
</p>
<h2>
<a asp-page="./Detail" asp-route-postUrl="@post.Url" asp-route-blogShortName="@Model.BlogShortName">@post.Title</a>
</h2>
<p class="article-sum">
@(post.Content == null ? "" : (post.Content.Length > 150 ? post.Content.Substring(0, 150) + "..." : post.Content))
</p>
<a asp-page="./Detail" asp-route-postUrl="@post.Url" asp-route-blogShortName="@Model.BlogShortName" class="btn btn-primary btn-rounded">@L["ContinueReading"]</a>
</div>
<div class="article-owner">
<div class="article-infos">
<div class="user-card">
<a>
<img src="https://placeimg.com/120/120/people" class="article-avatar">
</a>
<a>
<strong>Armağan Ünlü</strong>, @ConvertDatetimeToTimeAgo(post.CreationTime)
</a>
<span class="seperator">|</span>
<a>
<i class="fa fa-eye"></i> @post.ReadCount @L["Read"]
</a>
<span class="seperator">|</span>
<a>
<i class="fa fa-comment"></i> @post.CommentCount @L["Comment"]
</a>
</div>
</div>
</div>
</div>
</div>
}
</div>
</div>
}
</section>
</div>
<div class="col-md-4">
<h2>@L["WhatIsNew"]</h2>
<div class="list-group">
@for (var index = 0; index < Model.Posts.Count && index < 3; index++)
{
var post = Model.Posts[index];
@ -104,7 +128,7 @@
</div>
</div>
<div class="col-8 pl-0">
<h3>
<h3 class="font-125">
<a asp-page="./Detail" asp-route-postUrl="@post.Url" asp-route-blogShortName="@Model.BlogShortName">@post.Title</a>
</h3>
<div class="article-owner">
@ -122,116 +146,99 @@
</div>
}
</div>
@if (await Authorization.IsGrantedAsync(BloggingPermissions.Posts.Create))
{
<a asp-page="./New" asp-route-blogShortName="@Model.BlogShortName">@L["CreateANewPost"]</a>
}
</div>
</div>
</div>
<div class="container last-post-section pb-5">
<div class="pb-5">
<div class="row">
<div class="col-md-8">
<div class="row">
<div class="col">
<div class="titline">
<h2>@L["LastPosts"]</h2>
</div>
</div>
<div class="col-md-8 box-articles">
<div class="vs-blog-title">
<h2>@L["LastPosts"]</h2>
</div>
<div class="list-group">
@for (var index = 3; index < Model.Posts.Count; index++)
{
var post = Model.Posts[index];
var oddPost = index % 2 == 1;
@for (var index = 3; index < Model.Posts.Count; index++)
{
var post = Model.Posts[index];
var oddPost = index % 2 == 1;
<section class="box-articles">
<div class="row @(oddPost?"align-middle":"")">
<div class="col-md-4 order-md-@(oddPost?"last":"first")">
<div class="img-container">
<a asp-page="./Detail" asp-route-postUrl="@post.Url" asp-route-blogShortName="@Model.BlogShortName">
<img src="@post.CoverImage" class="box-article-img">
</a>
<div class="list-group-item">
<div class="row @(oddPost?"align-middle":"")">
<div class="col-md-4 order-md-@(oddPost?"last":"first")">
<div class="img-container">
<a asp-page="./Detail" asp-route-postUrl="@post.Url" asp-route-blogShortName="@Model.BlogShortName">
<img src="@post.CoverImage" class="box-article-img">
</a>
</div>
</div>
</div>
<div class="col-md-8 order-md-@(oddPost?"first":"last")">
<p class="tags">
@foreach (var tag in post.Tags)
{
<a asp-page="/Blog/Posts/Index" asp-route-blogShortName="@Model.BlogShortName" asp-route-tagName="@tag.Name" class="tag">@tag.Name</a>
}
</p>
<h3>
<a asp-page="./Detail" asp-route-postUrl="@post.Url" asp-route-blogShortName="@Model.BlogShortName">@post.Title</a>
</h3>
<p>
@(post.Content == null ? "" : (post.Content.Length > 250 ? post.Content.Substring(0, 150) : post.Content))...
</p>
<div class="article-owner">
<div class="article-infos">
<div class="user-card">
<a href="#">
<img src="https://placeimg.com/120/120/pople" class="article-avatar">
</a>
<a>
<strong>Armağan Ünlü</strong>, @ConvertDatetimeToTimeAgo(post.CreationTime)
</a>
<span class="seperator">|</span>
<a>
<i class="fa fa-eye"></i> @post.ReadCount
</a>
<span class="seperator">|</span>
<a>
<i class="fa fa-comment"></i> @post.CommentCount
</a>
<div class="col order-md-@(oddPost?"first":"last")">
<p class="tags">
@foreach (var tag in post.Tags)
{
<a asp-page="/Blog/Posts/Index" asp-route-blogShortName="@Model.BlogShortName" asp-route-tagName="@tag.Name" class="tag">@tag.Name</a>
}
</p>
<h3>
<a asp-page="./Detail" asp-route-postUrl="@post.Url" asp-route-blogShortName="@Model.BlogShortName">@post.Title</a>
</h3>
<p>
@(post.Content == null ? "" : (post.Content.Length > 250 ? post.Content.Substring(0, 150) : post.Content))...
</p>
<div class="article-owner">
<div class="article-infos">
<div class="user-card">
<a href="#">
<img src="https://placeimg.com/120/120/pople" class="article-avatar">
</a>
<a>
<strong>Armağan Ünlü</strong>, @ConvertDatetimeToTimeAgo(post.CreationTime)
</a>
<span class="vs-seperator">|</span>
<a>
<i class="fa fa-eye"></i> @post.ReadCount
</a>
<span class="vs-seperator">|</span>
<a>
<i class="fa fa-comment"></i> @post.CommentCount
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
}
}
</div>
</div>
<div class="col-md-4">
<div class="pb-5 sidebox" id="sidebar">
<div class="titline">
<h2>@L["PopularTags"]</h2>
</div>
<div class="sideboxes">
<div class="popular-tags">
@foreach (var popularTag in Model.PopularTags)
{
<a asp-page="/Blog/Posts/Index" asp-route-blogShortName="@Model.BlogShortName" asp-route-tagName="@popularTag.Name">@popularTag.Name <span>(@popularTag.UsageCount @L["Posts"])</span></a>
}
<div class="vs-blog-title">
<h2>@L["PopularTags"]</h2>
</div>
<div class="list-group small-list popular-tags">
@foreach (var popularTag in Model.PopularTags)
{
<div class="list-group-item">
<a asp-page="/Blog/Posts/Index" asp-route-blogShortName="@Model.BlogShortName" asp-route-tagName="@popularTag.Name">@popularTag.Name <span>(@popularTag.UsageCount @L["Posts"])</span></a>
</div>
</div>
}
<hr>
<footer>
<a href="#">About</a>
<span class="seperator">|</span>
<a href="#">Privacy Policy</a>
<span class="seperator">|</span>
<a href="#">Terms</a>
<p>
Copyright Volosoft - Blog
</p>
</footer>
</div>
<div class="vs-footer">
<a href="#">About</a>
<span class="vs-seperator">|</span>
<a href="#">Privacy Policy</a>
<span class="vs-seperator">|</span>
<a href="#">Terms</a>
<p>
&copy; Copyright Volosoft 2018 - Blog
</p>
</div>
</div>
</div>
</div>
</div>
</div>

1
modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Posts/New.cshtml.cs

@ -4,6 +4,7 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc.UI.RazorPages;
using Volo.Blogging.Blogs;
using Volo.Blogging.Blogs.Dtos;
using Volo.Blogging.Posts;
namespace Volo.Blogging.Pages.Blog.Posts

9
modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Posts/new.css.map

@ -0,0 +1,9 @@
{
"version": 3,
"file": "new.css",
"sources": [
"new.scss"
],
"mappings": "AAAA,AACI,sBADkB,CAClB,gBAAgB,AAAC,CACb,gBAAgB,CAAE,OAAQ,CAC1B,UAAU,CAAE,MAAO,CAKtB,AARL,AAKQ,sBALc,CAClB,gBAAgB,CAIZ,kBAAkB,AAAC,CACf,UAAU,CAAE,IAAK,CACpB,AAPT,AAUI,sBAVkB,CAUlB,KAAK,AAAC,CACF,gBAAgB,CAAE,OAAQ,CAC7B,AAZL,AAcI,sBAdkB,CAclB,cAAc,AAAC,CACX,UAAU,CAAE,MAAO,CACtB",
"names": []
}

3
modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Posts/new.min.css

@ -0,0 +1,3 @@
#qa-new-post-container .new-post-editor{background-color:#F9F9F9;min-height:19.5em}#qa-new-post-container .new-post-editor .CodeMirror-scroll{min-height:20em}#qa-new-post-container .card{background-color:#f6f8fa}#qa-new-post-container .loading-cover{min-height:19.5em}
/*# sourceMappingURL=new.css.map */

2
modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Shared/Scripts/blog.js

@ -28,7 +28,7 @@
autoplay: true,
autoHeight: true,
autoplaySpeed: 1000,
items: 1
items: 1,
});
$('.card-article-container .owl-carousel').owlCarousel({
loop: true,

169
modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Shared/Styles/_bootstrap-overwrite.scss

@ -1,4 +1,3 @@
a, a:hover {
text-decoration: none;
color: #000000;
@ -12,15 +11,15 @@ h1,h2,h3,h4,h5,h6,.tab-title {
font-weight: 700;
}
h1 {
font-size: 2.0em;
font-size: 2.25em;
margin: 1.5rem 0 .75rem;
}
h2, .tab-title {
font-size: 1.5em;
font-size: 1.75em;
margin: 1.5rem 0 .75rem;
}
h3 {
font-size: 1.25em;
font-size: 1.5em;
margin: 1.5rem 0 .75rem;
}
h4 {
@ -48,155 +47,57 @@ input, select, textarea, .form-control , .btn {
}
.no-border {
border: 0;
}
/* Owl overwrite */
.owl-theme .owl-nav {
margin-top: 0 !important;
text-align: center;
-webkit-tap-highlight-color: transparent;
position: absolute;
bottom: 120px;
left: 0;
right: 0;
font-size: 3em;
color: white;
> button {
width: 40px;
height: 40px;
padding: 0 !important;
display: inline-block !important;
line-height: 27px !important;
text-align: center;
background: none !important;
transition: .3s;
&.owl-next {
position: absolute;
right: 10%;
}
&.owl-prev {
position: absolute;
left: 10%;
}
> span {
width: 40px;
height: 40px;
padding: 0;
border: 2px solid white;
border-radius: 40px;
display: inline-block;
line-height: 29px;
text-align: center;
}
}
}
}
.btn-rounded {
border-radius: 30px;
}
.list-group {
.list-group {
.list-group-item {
position: relative;
display: block;
padding: 21px 0 21px 0;
margin-bottom: -1px;
background-color: #fff;
font-size: .8em;
padding: 0 0 20px 0;
background: none;
border-radius: 0;
border: 0;
border: 1px solid #f5f5f5;
border-width: 1px 0;
&:hover {
background: none;
}
&+.list-group-item {
margin-top: -1px;
& + .list-group-item {
border-top: 1px solid #f5f5f5;
padding: 20px 0;
}
h3 {
margin-top: 0;
}
}
}
.tab-content {
padding: 30px 0px 0;
}
.container {
padding-right: 20px;
padding-left: 20px;
}
.row {
margin-right: -20px;
margin-left: -20px;
}
.col, .col-1, .col-10, .col-11, .col-12, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-auto, .col-lg, .col-lg-1, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-auto, .col-md, .col-md-1, .col-md-10, .col-md-11, .col-md-12, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-auto, .col-sm, .col-sm-1, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-auto, .col-xl, .col-xl-1, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-auto {
padding-right: 20px;
padding-left: 20px;
}
@media (min-width: 1200px) {
.container {
max-width: 1080px;
&.small-list {
.list-group-item {
padding: 10px 0;
& + .list-group-item {
padding: 10px 0;
}
}
}
}
.font-75 {
font-size: .75em;
}
/*
.hero-container {
width: 96%;
max-width: 1440px;
}
*/
.f-85 {
.font-85 {
font-size: .85em;
}
.nav-tabs {
margin-bottom: 20px;
border-bottom: 3px solid #000;
.nav-item {
margin-bottom: -16px;
background: white;
border-left: 5px solid #fff;
.tab-title {
font-weight: 700;
line-height: 1.1;
padding: 7px;
margin-left: -14px;
}
}
.nav-link {
font-size: .8em;
border-radius: 50px;
padding: .25rem .5rem;
font-weight: 700;
color: grey;
&:hover, &:focus {
background:#eee;
}
}
.nav-link.active,
.nav-item.show .nav-link {
background: black;
border-color: white;
color: white;
border-radius: 50px;
}
}
.pb-5, .py-5 {
padding-bottom: 4rem!important;
.font-92 {
font-size: .92em;
}
.pt-5, .py-5 {
padding-top: 4rem!important;
.font-100 {
font-size: 1em;
}
footer {
font-size: .8em;
line-height: 2;
.seperator {
padding: 0 5px;
opacity: .5;
}
}
.font-125 {
font-size: 1.25em;
}

40
modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Shared/Styles/_header.scss

@ -1,19 +1,21 @@
header {
position: fixed;
width: 100%;
top: 0;
left: 0;
z-index: 100;
background:#f8f9fa;
.navbar-blog {
padding: 20px 0;
ul {
li {
a {
color: black;
}
}
}
}
}
.vs-blog-title {
padding-bottom: 15px;
margin-bottom: 25px;
border-bottom: 1px solid #ddd;
h1,h2,h3,h4,h5, h6 {
margin: 0;
padding: 0;
}
}
.vs-footer {
padding-top: 15px;
margin-top: 25px;
border-top: 1px solid #ddd;
}
.vs-seperator {
padding: 0 4px;
opacity: .3;
}

140
modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Shared/Styles/_home.css

@ -0,0 +1,140 @@
.hero-section {
padding: 0; }
.hero-section .hero-articles {
position: relative;
overflow: hidden; }
.hero-section .hero-articles .hero-content {
position: absolute;
left: 12%;
right: 12%;
bottom: 80px;
z-index: 4;
text-align: center; }
.hero-section .hero-articles .hero-content h2 {
margin-top: 0;
font-size: 2.5em;
font-weight: bold; }
.hero-section .hero-articles .hero-content a {
color: white;
text-shadow: 0px 0px 20px rgba(0, 0, 0, 0.5); }
.hero-section .hero-articles .hero-content p {
color: white; }
.hero-section .hero-articles .tags .tag {
background: rgba(208, 208, 208, 0.3);
color: #fff !important; }
.hero-section .hero-articles .tags .tag:hover {
background: white;
color: black !important; }
.hero-section .hero-articles .article-owner {
text-align: center;
position: relative;
z-index: 12; }
.hero-section .hero-articles .article-owner .article-infos {
color: black; }
.hero-section .hero-articles .article-owner .article-infos a {
color: black; }
.hero-section .hero-articles .article-owner .article-infos .seperator {
margin: 0 4px;
color: rgba(255, 255, 255, 0.2); }
.hero-section .hero-articles .article-owner .article-infos img.article-avatar {
width: 64px;
margin: -25px 10px 0px 0;
border: 3px solid #fff;
display: inline-block;
border-radius: 50%; }
.hero-section .hero-articles .img-container {
background: black; }
.hero-section .hero-articles .img-container img {
filter: grayscale(10%); }
.hero-section .hero-articles .img-container::after {
content: "";
display: block;
position: absolute;
z-index: 1;
bottom: 0px;
width: 100%;
top: 1% !important;
background: linear-gradient(to bottom, transparent 0, rgba(0, 0, 0, 0.91) 89%, rgba(0, 0, 0, 0.93) 93%) !important;
transition: .2s all ease-in-out;
opacity: .9; }
.hero-section .hero-articles:hover .img-container::after {
opacity: 1; }
.article-owner .article-infos {
color: #000; }
.article-owner .article-infos a {
color: rgba(0, 0, 0, 0.6); }
.article-owner .article-infos .seperator {
margin: 0 4px;
color: rgba(0, 0, 0, 0.2); }
.article-owner .article-infos img.article-avatar {
width: 30px;
margin: -1px 4px 0 0;
display: inline-block;
border-radius: 50%; }
.card-articles .card-content {
padding: 10px 0px 10px; }
.card-articles .card-content h3 {
margin: 10px 0; }
.card-articles .card-content h3 a {
font-weight: 700; }
.card-articles .article-owner {
text-align: left; }
.card-articles .article-owner .article-infos {
color: #000; }
.card-articles .article-owner .article-infos a {
color: rgba(0, 0, 0, 0.6); }
.card-articles .article-owner .article-infos .seperator {
margin: 0 4px;
color: rgba(0, 0, 0, 0.2); }
.card-articles .article-owner .article-infos img.article-avatar {
width: 30px;
margin: -1px 4px 0 0;
display: inline-block;
border-radius: 50%; }
.article-owner {
font-size: .85em; }
.user-link-icons {
position: absolute;
right: 18px;
top: 15px;
z-index: 3; }
.user-link-icons a {
display: inline-block;
color: #eee;
margin-left: 12px;
font-size: 1.25em; }
.user-link-icons a:hover {
color: #fff; }
.tags .tag {
display: inline-block;
padding: 2px 8px;
background: rgba(208, 208, 208, 0.3);
border-radius: 30px;
margin: 0 1px 3px 0;
color: #b1b1b1 !important;
font-size: .7em;
line-height: 1.6em;
text-transform: uppercase; }
.tags .tag:hover {
background: black;
color: white !important; }
.popular-tags a {
display: block;
font-size: .9em; }
.popular-tags a span {
float: right;
opacity: .3;
font-size: .9em; }
.img-container {
position: relative;
overflow: hidden;
border-radius: 4px; }

1
modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Shared/Styles/_home.min.css

@ -0,0 +1 @@
.hero-section{padding:0;}.hero-section .hero-articles{position:relative;overflow:hidden;}.hero-section .hero-articles .hero-content{position:absolute;left:12%;right:12%;bottom:80px;z-index:4;text-align:center;}.hero-section .hero-articles .hero-content h2{margin-top:0;font-size:2.5em;font-weight:bold;}.hero-section .hero-articles .hero-content a{color:#fff;text-shadow:0 0 20px rgba(0,0,0,.5);}.hero-section .hero-articles .hero-content p{color:#fff;}.hero-section .hero-articles .tags .tag{background:rgba(208,208,208,.3);color:#fff !important;}.hero-section .hero-articles .tags .tag:hover{background:#fff;color:#000 !important;}.hero-section .hero-articles .article-owner{text-align:center;position:relative;z-index:12;}.hero-section .hero-articles .article-owner .article-infos{color:#000;}.hero-section .hero-articles .article-owner .article-infos a{color:#000;}.hero-section .hero-articles .article-owner .article-infos .seperator{margin:0 4px;color:rgba(255,255,255,.2);}.hero-section .hero-articles .article-owner .article-infos img.article-avatar{width:64px;margin:-25px 10px 0 0;border:3px solid #fff;display:inline-block;border-radius:50%;}.hero-section .hero-articles .img-container{background:#000;}.hero-section .hero-articles .img-container img{filter:grayscale(10%);}.hero-section .hero-articles .img-container::after{content:"";display:block;position:absolute;z-index:1;bottom:0;width:100%;top:1% !important;background:linear-gradient(to bottom,transparent 0,rgba(0,0,0,.91) 89%,rgba(0,0,0,.93) 93%) !important;transition:.2s all ease-in-out;opacity:.9;}.hero-section .hero-articles:hover .img-container::after{opacity:1;}.article-owner .article-infos{color:#000;}.article-owner .article-infos a{color:rgba(0,0,0,.6);}.article-owner .article-infos .seperator{margin:0 4px;color:rgba(0,0,0,.2);}.article-owner .article-infos img.article-avatar{width:30px;margin:-1px 4px 0 0;display:inline-block;border-radius:50%;}.card-articles .card-content{padding:10px 0 10px;}.card-articles .card-content h3{margin:10px 0;}.card-articles .card-content h3 a{font-weight:700;}.card-articles .article-owner{text-align:left;}.card-articles .article-owner .article-infos{color:#000;}.card-articles .article-owner .article-infos a{color:rgba(0,0,0,.6);}.card-articles .article-owner .article-infos .seperator{margin:0 4px;color:rgba(0,0,0,.2);}.card-articles .article-owner .article-infos img.article-avatar{width:30px;margin:-1px 4px 0 0;display:inline-block;border-radius:50%;}.article-owner{font-size:.85em;}.user-link-icons{position:absolute;right:18px;top:15px;z-index:3;}.user-link-icons a{display:inline-block;color:#eee;margin-left:12px;font-size:1.25em;}.user-link-icons a:hover{color:#fff;}.tags .tag{display:inline-block;padding:2px 8px;background:rgba(208,208,208,.3);border-radius:30px;margin:0 1px 3px 0;color:#b1b1b1 !important;font-size:.7em;line-height:1.6em;text-transform:uppercase;}.tags .tag:hover{background:#000;color:#fff !important;}.popular-tags a{display:block;font-size:.9em;}.popular-tags a span{float:right;opacity:.3;font-size:.9em;}.img-container{position:relative;overflow:hidden;border-radius:4px;}

88
modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Shared/Styles/_home.scss

@ -1,4 +1,4 @@
section.hero-section {
.hero-section {
padding: 0;
.hero-articles {
position: relative;
@ -57,9 +57,7 @@ section.hero-section {
}
}
.img-container {
background: black;
border-top-left-radius: 0;
border-top-right-radius: 0;
background: black;
img {
filter: grayscale(10%);
}
@ -85,39 +83,26 @@ section.hero-section {
}
}
}
.box-articles {
padding: 0 0 40px 0;
&+.box-articles {
padding: 40px 0;
border-top: 1px solid #f5f5f5;
border-bottom: 1px solid #f5f5f5;
margin-top: -1px;
}
h3 {
margin: 10px 0;
.article-owner {
.article-infos {
color: #000;
a {
font-weight: 700;
color: rgba(0, 0, 0, 0.6);
}
}
.article-owner {
.article-infos {
color: #000;
a {
color: rgba(0, 0, 0, 0.6);
}
.seperator {
margin: 0 4px;
color: rgba(0, 0, 0, 0.2);
}
img.article-avatar {
width: 30px;
margin: -1px 4px 0 0;
display: inline-block;
border-radius: 50%;
}
.seperator {
margin: 0 4px;
color: rgba(0, 0, 0, 0.2);
}
}
}
img.article-avatar {
width: 30px;
margin: -1px 4px 0 0;
display: inline-block;
border-radius: 50%;
}
}
}
.card-articles {
.card-content
@ -172,37 +157,32 @@ section.hero-section {
}
.tags {
margin:5px 0;
.tag {
display: inline-block;
padding: 0px 6px;
padding: 2px 8px;
background: rgba(208, 208, 208, 0.3);
border-radius: 30px;
margin: 4px 1px;
margin: 0 1px 3px 0;
color: #b1b1b1 !important;
font-size: .64em;
font-size: .7em;
line-height: 1.6em;
text-transform: uppercase;
&:hover {
background: black;
&:hover {
background: black;
color: white !important;
}
}
}
}
}
.popular-tags {
a {
display: block;
padding: 10px 15px;
background: white;
margin-bottom: 2px;
font-size: .85em;
&:hover {
background: #f5f5f5;
}
font-size: .9em;
span {
float: right;
opacity: .3;
font-size: .85em;
font-size: .9em;
}
}
}
@ -213,10 +193,4 @@ section.hero-section {
overflow: hidden;
border-radius: 4px;
}
.sidebox {
.sideboxes {
padding: 30px;
background: #fafafa;
}
}

30
modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Shared/Styles/_post.scss

@ -52,32 +52,36 @@
.media {
font-size: .95em;
}
}
}
.comment-area {
.comment-owner {
margin-bottom: 2px;
span {
font-weight: 300;
color: #999;
font-size: .8em;
}
}
>.media {
padding: 30px 0;
> .media {
padding: 30px 0;
border-bottom: 1px solid #f1f1f1;
.media {
padding: 20px 0;
padding: 20px 0;
}
}
.comment-buttons {
background: #f8f9fa ;
border-bottom: 1px solid #f1f1f1;
padding: 6px 10px;
font-size: .85em;
padding: 4px 8px;
.seperator {
color: #ddd;
margin: 0 8px;
}
.count {
color: #fff;
background: #ddd;
@ -85,17 +89,27 @@
padding: 1px 3px;
font-size: 10px;
border-radius: 3px;
&.count-up {
background: #999;
}
}
a {
opacity: .5;
&:hover {
opacity: .75;
}
}
}
p {
margin-bottom: 6px;
}
.comment-avatar {
width: 64px;
}
.answer-avatar {
width: 48px;
}

289
modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Shared/Styles/blog.css

@ -1,15 +1,9 @@
div.vs-blog {
position: relative;
background: #fff;
font-family: Helvetica, sans-serif;
font-size: 15px;
/* Owl overwrite */
/*
.hero-container {
width: 96%;
max-width: 1440px;
}
*/ }
background: white;
padding: 0 30px;
font-family: 'Open Sans', Helvetica, Arial, sans-serif;
font-size: 14px; }
div.vs-blog a, div.vs-blog a:hover {
text-decoration: none;
color: #000000; }
@ -20,13 +14,13 @@
font-family: Helvetica, Roboto, sans-serif;
font-weight: 700; }
div.vs-blog h1 {
font-size: 2.0em;
font-size: 2.25em;
margin: 1.5rem 0 .75rem; }
div.vs-blog h2, div.vs-blog .tab-title {
font-size: 1.5em;
font-size: 1.75em;
margin: 1.5rem 0 .75rem; }
div.vs-blog h3 {
font-size: 1.25em;
font-size: 1.5em;
margin: 1.5rem 0 .75rem; }
div.vs-blog h4 {
font-size: 1.25em;
@ -46,172 +40,99 @@
background: aqua; }
div.vs-blog .no-border {
border: 0; }
div.vs-blog .owl-theme .owl-nav {
margin-top: 0 !important;
text-align: center;
-webkit-tap-highlight-color: transparent;
position: absolute;
bottom: 120px;
left: 0;
right: 0;
font-size: 3em;
color: white; }
div.vs-blog .owl-theme .owl-nav > button {
width: 40px;
height: 40px;
padding: 0 !important;
display: inline-block !important;
line-height: 27px !important;
text-align: center;
background: none !important;
transition: .3s; }
div.vs-blog .owl-theme .owl-nav > button.owl-next {
position: absolute;
right: 10%; }
div.vs-blog .owl-theme .owl-nav > button.owl-prev {
position: absolute;
left: 10%; }
div.vs-blog .owl-theme .owl-nav > button > span {
width: 40px;
height: 40px;
padding: 0;
border: 2px solid white;
border-radius: 40px;
display: inline-block;
line-height: 29px;
text-align: center; }
div.vs-blog .btn-rounded {
border-radius: 30px; }
div.vs-blog .list-group .list-group-item {
position: relative;
display: block;
padding: 21px 0 21px 0;
margin-bottom: -1px;
background-color: #fff;
font-size: .8em;
border: 0;
border: 1px solid #f5f5f5;
border-width: 1px 0; }
padding: 0 0 20px 0;
background: none;
border-radius: 0;
border: 0; }
div.vs-blog .list-group .list-group-item:hover {
background: none; }
div.vs-blog .list-group .list-group-item + .list-group-item {
margin-top: -1px; }
border-top: 1px solid #f5f5f5;
padding: 20px 0; }
div.vs-blog .list-group .list-group-item h3 {
margin-top: 0; }
div.vs-blog .tab-content {
padding: 30px 0px 0; }
div.vs-blog .container {
padding-right: 20px;
padding-left: 20px; }
div.vs-blog .row {
margin-right: -20px;
margin-left: -20px; }
div.vs-blog .col, div.vs-blog .col-1, div.vs-blog .col-10, div.vs-blog .col-11, div.vs-blog .col-12, div.vs-blog .col-2, div.vs-blog .col-3, div.vs-blog .col-4, div.vs-blog .col-5, div.vs-blog .col-6, div.vs-blog .col-7, div.vs-blog .col-8, div.vs-blog .col-9, div.vs-blog .col-auto, div.vs-blog .col-lg, div.vs-blog .col-lg-1, div.vs-blog .col-lg-10, div.vs-blog .col-lg-11, div.vs-blog .col-lg-12, div.vs-blog .col-lg-2, div.vs-blog .col-lg-3, div.vs-blog .col-lg-4, div.vs-blog .col-lg-5, div.vs-blog .col-lg-6, div.vs-blog .col-lg-7, div.vs-blog .col-lg-8, div.vs-blog .col-lg-9, div.vs-blog .col-lg-auto, div.vs-blog .col-md, div.vs-blog .col-md-1, div.vs-blog .col-md-10, div.vs-blog .col-md-11, div.vs-blog .col-md-12, div.vs-blog .col-md-2, div.vs-blog .col-md-3, div.vs-blog .col-md-4, div.vs-blog .col-md-5, div.vs-blog .col-md-6, div.vs-blog .col-md-7, div.vs-blog .col-md-8, div.vs-blog .col-md-9, div.vs-blog .col-md-auto, div.vs-blog .col-sm, div.vs-blog .col-sm-1, div.vs-blog .col-sm-10, div.vs-blog .col-sm-11, div.vs-blog .col-sm-12, div.vs-blog .col-sm-2, div.vs-blog .col-sm-3, div.vs-blog .col-sm-4, div.vs-blog .col-sm-5, div.vs-blog .col-sm-6, div.vs-blog .col-sm-7, div.vs-blog .col-sm-8, div.vs-blog .col-sm-9, div.vs-blog .col-sm-auto, div.vs-blog .col-xl, div.vs-blog .col-xl-1, div.vs-blog .col-xl-10, div.vs-blog .col-xl-11, div.vs-blog .col-xl-12, div.vs-blog .col-xl-2, div.vs-blog .col-xl-3, div.vs-blog .col-xl-4, div.vs-blog .col-xl-5, div.vs-blog .col-xl-6, div.vs-blog .col-xl-7, div.vs-blog .col-xl-8, div.vs-blog .col-xl-9, div.vs-blog .col-xl-auto {
padding-right: 20px;
padding-left: 20px; }
@media (min-width: 1200px) {
div.vs-blog .container {
max-width: 1080px; } }
div.vs-blog .f-85 {
div.vs-blog .list-group.small-list .list-group-item {
padding: 10px 0; }
div.vs-blog .list-group.small-list .list-group-item + .list-group-item {
padding: 10px 0; }
div.vs-blog .font-75 {
font-size: .75em; }
div.vs-blog .font-85 {
font-size: .85em; }
div.vs-blog .nav-tabs {
margin-bottom: 20px;
border-bottom: 3px solid #000; }
div.vs-blog .nav-tabs .nav-item {
margin-bottom: -16px;
background: white;
border-left: 5px solid #fff; }
div.vs-blog .nav-tabs .nav-item .tab-title {
font-weight: 700;
line-height: 1.1;
padding: 7px;
margin-left: -14px; }
div.vs-blog .nav-tabs .nav-link {
font-size: .8em;
border-radius: 50px;
padding: .25rem .5rem;
font-weight: 700;
color: grey; }
div.vs-blog .nav-tabs .nav-link:hover, div.vs-blog .nav-tabs .nav-link:focus {
background: #eee; }
div.vs-blog .nav-tabs .nav-link.active,
div.vs-blog .nav-tabs .nav-item.show .nav-link {
background: black;
border-color: white;
color: white;
border-radius: 50px; }
div.vs-blog .pb-5, div.vs-blog .py-5 {
padding-bottom: 4rem !important; }
div.vs-blog .pt-5, div.vs-blog .py-5 {
padding-top: 4rem !important; }
div.vs-blog footer {
font-size: .8em;
line-height: 2; }
div.vs-blog footer .seperator {
padding: 0 5px;
opacity: .5; }
div.vs-blog header {
position: fixed;
width: 100%;
top: 0;
left: 0;
z-index: 100;
background: #f8f9fa; }
div.vs-blog header .navbar-blog {
padding: 20px 0; }
div.vs-blog header .navbar-blog ul li a {
color: black; }
div.vs-blog section.hero-section {
div.vs-blog .font-92 {
font-size: .92em; }
div.vs-blog .font-100 {
font-size: 1em; }
div.vs-blog .font-125 {
font-size: 1.25em; }
div.vs-blog .vs-blog-title {
padding-bottom: 15px;
margin-bottom: 25px;
border-bottom: 1px solid #ddd; }
div.vs-blog .vs-blog-title h1, div.vs-blog .vs-blog-title h2, div.vs-blog .vs-blog-title h3, div.vs-blog .vs-blog-title h4, div.vs-blog .vs-blog-title h5, div.vs-blog .vs-blog-title h6 {
margin: 0;
padding: 0; }
div.vs-blog .vs-footer {
padding-top: 15px;
margin-top: 25px;
border-top: 1px solid #ddd; }
div.vs-blog .vs-seperator {
padding: 0 4px;
opacity: .3; }
div.vs-blog .hero-section {
padding: 0; }
div.vs-blog section.hero-section .hero-articles {
div.vs-blog .hero-section .hero-articles {
position: relative;
overflow: hidden; }
div.vs-blog section.hero-section .hero-articles .hero-content {
div.vs-blog .hero-section .hero-articles .hero-content {
position: absolute;
left: 12%;
right: 12%;
bottom: 80px;
z-index: 4;
text-align: center; }
div.vs-blog section.hero-section .hero-articles .hero-content h2 {
div.vs-blog .hero-section .hero-articles .hero-content h2 {
margin-top: 0;
font-size: 2.5em;
font-weight: bold; }
div.vs-blog section.hero-section .hero-articles .hero-content a {
div.vs-blog .hero-section .hero-articles .hero-content a {
color: white;
text-shadow: 0px 0px 20px rgba(0, 0, 0, 0.5); }
div.vs-blog section.hero-section .hero-articles .hero-content p {
div.vs-blog .hero-section .hero-articles .hero-content p {
color: white; }
div.vs-blog section.hero-section .hero-articles .tags .tag {
div.vs-blog .hero-section .hero-articles .tags .tag {
background: rgba(208, 208, 208, 0.3);
color: #fff !important; }
div.vs-blog section.hero-section .hero-articles .tags .tag:hover {
div.vs-blog .hero-section .hero-articles .tags .tag:hover {
background: white;
color: black !important; }
div.vs-blog section.hero-section .hero-articles .article-owner {
div.vs-blog .hero-section .hero-articles .article-owner {
text-align: center;
position: relative;
z-index: 12; }
div.vs-blog section.hero-section .hero-articles .article-owner .article-infos {
div.vs-blog .hero-section .hero-articles .article-owner .article-infos {
color: black; }
div.vs-blog section.hero-section .hero-articles .article-owner .article-infos a {
div.vs-blog .hero-section .hero-articles .article-owner .article-infos a {
color: black; }
div.vs-blog section.hero-section .hero-articles .article-owner .article-infos .seperator {
div.vs-blog .hero-section .hero-articles .article-owner .article-infos .seperator {
margin: 0 4px;
color: rgba(255, 255, 255, 0.2); }
div.vs-blog section.hero-section .hero-articles .article-owner .article-infos img.article-avatar {
div.vs-blog .hero-section .hero-articles .article-owner .article-infos img.article-avatar {
width: 64px;
margin: -25px 10px 0px 0;
border: 3px solid #fff;
display: inline-block;
border-radius: 50%; }
div.vs-blog section.hero-section .hero-articles .img-container {
background: black;
border-top-left-radius: 0;
border-top-right-radius: 0; }
div.vs-blog section.hero-section .hero-articles .img-container img {
div.vs-blog .hero-section .hero-articles .img-container {
background: black; }
div.vs-blog .hero-section .hero-articles .img-container img {
filter: grayscale(10%); }
div.vs-blog section.hero-section .hero-articles .img-container::after {
div.vs-blog .hero-section .hero-articles .img-container::after {
content: "";
display: block;
position: absolute;
@ -222,31 +143,20 @@
background: linear-gradient(to bottom, transparent 0, rgba(0, 0, 0, 0.91) 89%, rgba(0, 0, 0, 0.93) 93%) !important;
transition: .2s all ease-in-out;
opacity: .9; }
div.vs-blog section.hero-section .hero-articles:hover .img-container::after {
div.vs-blog .hero-section .hero-articles:hover .img-container::after {
opacity: 1; }
div.vs-blog .box-articles {
padding: 0 0 40px 0; }
div.vs-blog .box-articles + .box-articles {
padding: 40px 0;
border-top: 1px solid #f5f5f5;
border-bottom: 1px solid #f5f5f5;
margin-top: -1px; }
div.vs-blog .box-articles h3 {
margin: 10px 0; }
div.vs-blog .box-articles h3 a {
font-weight: 700; }
div.vs-blog .box-articles .article-owner .article-infos {
color: #000; }
div.vs-blog .box-articles .article-owner .article-infos a {
color: rgba(0, 0, 0, 0.6); }
div.vs-blog .box-articles .article-owner .article-infos .seperator {
margin: 0 4px;
color: rgba(0, 0, 0, 0.2); }
div.vs-blog .box-articles .article-owner .article-infos img.article-avatar {
width: 30px;
margin: -1px 4px 0 0;
display: inline-block;
border-radius: 50%; }
div.vs-blog .article-owner .article-infos {
color: #000; }
div.vs-blog .article-owner .article-infos a {
color: rgba(0, 0, 0, 0.6); }
div.vs-blog .article-owner .article-infos .seperator {
margin: 0 4px;
color: rgba(0, 0, 0, 0.2); }
div.vs-blog .article-owner .article-infos img.article-avatar {
width: 30px;
margin: -1px 4px 0 0;
display: inline-block;
border-radius: 50%; }
div.vs-blog .card-articles .card-content {
padding: 10px 0px 10px; }
div.vs-blog .card-articles .card-content h3 {
@ -281,40 +191,30 @@
font-size: 1.25em; }
div.vs-blog .user-link-icons a:hover {
color: #fff; }
div.vs-blog .tags {
margin: 5px 0; }
div.vs-blog .tags .tag {
display: inline-block;
padding: 0px 6px;
background: rgba(208, 208, 208, 0.3);
border-radius: 30px;
margin: 4px 1px;
color: #b1b1b1 !important;
font-size: .64em;
line-height: 1.6em;
text-transform: uppercase; }
div.vs-blog .tags .tag:hover {
background: black;
color: white !important; }
div.vs-blog .tags .tag {
display: inline-block;
padding: 2px 8px;
background: rgba(208, 208, 208, 0.3);
border-radius: 30px;
margin: 0 1px 3px 0;
color: #b1b1b1 !important;
font-size: .7em;
line-height: 1.6em;
text-transform: uppercase; }
div.vs-blog .tags .tag:hover {
background: black;
color: white !important; }
div.vs-blog .popular-tags a {
display: block;
padding: 10px 15px;
background: white;
margin-bottom: 2px;
font-size: .85em; }
div.vs-blog .popular-tags a:hover {
background: #f5f5f5; }
font-size: .9em; }
div.vs-blog .popular-tags a span {
float: right;
opacity: .3;
font-size: .85em; }
font-size: .9em; }
div.vs-blog .img-container {
position: relative;
overflow: hidden;
border-radius: 4px; }
div.vs-blog .sidebox .sideboxes {
padding: 30px;
background: #fafafa; }
div.vs-blog .post-detail h1 {
padding: 0px 0;
line-height: 1.25em;
@ -354,20 +254,19 @@
font-size: .95em; }
div.vs-blog .media .media {
font-size: .95em; }
div.vs-blog .comment-area .comment-owner span {
font-weight: 300;
color: #999;
font-size: .8em; }
div.vs-blog .comment-area .comment-owner {
margin-bottom: 2px; }
div.vs-blog .comment-area .comment-owner span {
font-weight: 300;
color: #999;
font-size: .8em; }
div.vs-blog .comment-area > .media {
padding: 30px 0;
border-bottom: 1px solid #f1f1f1; }
div.vs-blog .comment-area > .media .media {
padding: 20px 0; }
div.vs-blog .comment-area .comment-buttons {
background: #f8f9fa;
border-bottom: 1px solid #f1f1f1;
padding: 6px 10px;
font-size: .85em; }
padding: 4px 8px; }
div.vs-blog .comment-area .comment-buttons .seperator {
color: #ddd;
margin: 0 8px; }
@ -380,6 +279,10 @@
border-radius: 3px; }
div.vs-blog .comment-area .comment-buttons .count.count-up {
background: #999; }
div.vs-blog .comment-area .comment-buttons a {
opacity: .5; }
div.vs-blog .comment-area .comment-buttons a:hover {
opacity: .75; }
div.vs-blog .comment-area p {
margin-bottom: 6px; }
div.vs-blog .comment-area .comment-avatar {

24
modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Shared/Styles/blog.css.map

File diff suppressed because one or more lines are too long

2
modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Shared/Styles/blog.min.css

File diff suppressed because one or more lines are too long

18
modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Shared/Styles/blog.scss

@ -1,11 +1,13 @@
div.vs-blog {
position: relative;
background: #fff;
font-family: Helvetica, sans-serif;
font-size: 15px;
background: white;
padding: 0 30px;
font-family: 'Open Sans', Helvetica, Arial, sans-serif;
font-size: 14px;
@import "bootstrap-overwrite.scss";
@import "header.scss";
@import "home.scss";
@import "post.scss";
@import "custom.scss";
}
@import "header.scss";
@import "home.scss";
@import "post.scss";
@import "custom.scss";
}

2
modules/blogging/src/Volo.Blogging.Web/Volo.Blogging.Web.csproj

@ -36,6 +36,8 @@
<Content Remove="Pages\**\*.css" />
<Content Remove="compilerconfig.json" />
<Content Remove="Properties\launchSettings.json" />
<None Remove="Pages\Admin\Blogs\create.js" />
<None Remove="Pages\Admin\Blogs\edit.js" />
<None Include="compilerconfig.json" />
<None Include="Properties\launchSettings.json" />
</ItemGroup>

4
modules/blogging/src/Volo.Blogging.Web/compilerconfig.json

@ -2,5 +2,9 @@
{
"outputFile": "Pages/Blog/Shared/Styles/blog.css",
"inputFile": "Pages/Blog/Shared/Styles/blog.scss"
},
{
"outputFile": "Pages/Blog/Shared/Styles/_home.css",
"inputFile": "Pages/Blog/Shared/Styles/_home.scss"
}
]
Loading…
Cancel
Save