Merge pull request #5028 from sbwalker/dev

add caching support for folders
This commit is contained in:
Shaun Walker 2025-01-28 12:47:37 -05:00 committed by GitHub
commit 1db83f509b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 63 additions and 11 deletions

View File

@ -49,18 +49,24 @@
} }
</div> </div>
</div> </div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="imagesizes" HelpText="Enter a list of image sizes which can be generated dynamically from uploaded images (ie. 200x200,400x400). Use * to indicate the folder supports all image sizes." ResourceKey="ImageSizes">Image Sizes: </Label>
<div class="col-sm-9">
<input id="imagesizes" class="form-control" @bind="@_imagesizes" maxlength="512" />
</div>
</div>
<div class="row mb-1 align-items-center"> <div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="capacity" HelpText="Enter the maximum folder capacity (in megabytes). Specify zero if the capacity is unlimited." ResourceKey="Capacity">Capacity: </Label> <Label Class="col-sm-3" For="capacity" HelpText="Enter the maximum folder capacity (in megabytes). Specify zero if the capacity is unlimited." ResourceKey="Capacity">Capacity: </Label>
<div class="col-sm-9"> <div class="col-sm-9">
<input id="capacity" class="form-control" @bind="@_capacity" required /> <input id="capacity" class="form-control" @bind="@_capacity" required />
</div> </div>
</div> </div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="cachecontrol" HelpText="Optionally provide a Cache-Control directive for this folder. For example 'public, max-age=604800' indicates that files in this folder should be cached for 1 week." ResourceKey="CacheControl">Caching: </Label>
<div class="col-sm-9">
<input id="cachecontrol" class="form-control" @bind="@_cachecontrol" maxlength="50" />
</div>
</div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="imagesizes" HelpText="Optionally enter a list of image sizes which can be generated dynamically from uploaded images (ie. 200x200,400x400). Use * to indicate the folder supports all image sizes (not recommended)." ResourceKey="ImageSizes">Image Sizes: </Label>
<div class="col-sm-9">
<input id="imagesizes" class="form-control" @bind="@_imagesizes" maxlength="512" />
</div>
</div>
</div> </div>
@if (PageState.QueryString.ContainsKey("id")) @if (PageState.QueryString.ContainsKey("id"))
{ {
@ -100,8 +106,9 @@
private int _parentId = -1; private int _parentId = -1;
private string _name; private string _name;
private string _type = FolderTypes.Private; private string _type = FolderTypes.Private;
private string _imagesizes = string.Empty;
private string _capacity = "0"; private string _capacity = "0";
private string _cachecontrol = string.Empty;
private string _imagesizes = string.Empty;
private bool _isSystem; private bool _isSystem;
private List<Permission> _permissions = null; private List<Permission> _permissions = null;
private string _createdBy; private string _createdBy;
@ -132,8 +139,9 @@
_parentId = folder.ParentId ?? -1; _parentId = folder.ParentId ?? -1;
_name = folder.Name; _name = folder.Name;
_type = folder.Type; _type = folder.Type;
_imagesizes = folder.ImageSizes;
_capacity = folder.Capacity.ToString(); _capacity = folder.Capacity.ToString();
_cachecontrol = folder.CacheControl;
_imagesizes = folder.ImageSizes;
_isSystem = folder.IsSystem; _isSystem = folder.IsSystem;
_permissions = folder.PermissionList; _permissions = folder.PermissionList;
_createdBy = folder.CreatedBy; _createdBy = folder.CreatedBy;
@ -193,7 +201,7 @@
{ {
folder.ParentId = _parentId; folder.ParentId = _parentId;
} }
// check for duplicate folder names // check for duplicate folder names
if (_folders.Any(item => item.ParentId == folder.ParentId && item.Name == _name && item.FolderId != _folderId)) if (_folders.Any(item => item.ParentId == folder.ParentId && item.Name == _name && item.FolderId != _folderId))
{ {
@ -204,8 +212,9 @@
folder.SiteId = PageState.Site.SiteId; folder.SiteId = PageState.Site.SiteId;
folder.Name = _name; folder.Name = _name;
folder.Type = _type; folder.Type = _type;
folder.ImageSizes = _imagesizes;
folder.Capacity = int.Parse(_capacity); folder.Capacity = int.Parse(_capacity);
folder.CacheControl = _cachecontrol;
folder.ImageSizes = _imagesizes;
folder.IsSystem = _isSystem; folder.IsSystem = _isSystem;
folder.PermissionList = _permissionGrid.GetPermissionList(); folder.PermissionList = _permissionGrid.GetPermissionList();

View File

@ -175,7 +175,7 @@
<value>Capacity:</value> <value>Capacity:</value>
</data> </data>
<data name="ImageSizes.HelpText" xml:space="preserve"> <data name="ImageSizes.HelpText" xml:space="preserve">
<value>Enter a list of image sizes which can be generated dynamically from uploaded images (ie. 200x200,400x400). Use * to indicate the folder supports all image sizes.</value> <value>Optionally enter a list of image sizes which can be generated dynamically from uploaded images (ie. 200x200,400x400). Use * to indicate the folder supports all image sizes.</value>
</data> </data>
<data name="ImageSizes.Text" xml:space="preserve"> <data name="ImageSizes.Text" xml:space="preserve">
<value>Image Sizes:</value> <value>Image Sizes:</value>
@ -198,4 +198,10 @@
<data name="Settings.Heading" xml:space="preserve"> <data name="Settings.Heading" xml:space="preserve">
<value>Settings</value> <value>Settings</value>
</data> </data>
<data name="CacheControl.Text" xml:space="preserve">
<value>Caching:</value>
</data>
<data name="CacheControl.HelpText" xml:space="preserve">
<value>Optionally provide a Cache-Control directive for this folder. For example 'public, max-age=604800' indicates that files in this folder should be cached for 1 week.</value>
</data>
</root> </root>

View File

@ -0,0 +1,28 @@
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Oqtane.Databases.Interfaces;
using Oqtane.Migrations.EntityBuilders;
using Oqtane.Repository;
namespace Oqtane.Migrations.Tenant
{
[DbContext(typeof(TenantDBContext))]
[Migration("Tenant.06.00.02.01")]
public class AddFolderCacheControl : MultiDatabaseMigration
{
public AddFolderCacheControl(IDatabase database) : base(database)
{
}
protected override void Up(MigrationBuilder migrationBuilder)
{
var folderEntityBuilder = new FolderEntityBuilder(migrationBuilder, ActiveDatabase);
folderEntityBuilder.AddStringColumn("CacheControl", 50, true);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
// not implemented
}
}
}

View File

@ -257,6 +257,10 @@ namespace Oqtane.Pages
} }
else else
{ {
if (!string.IsNullOrEmpty(file.Folder.CacheControl))
{
HttpContext.Response.Headers.Append(HeaderNames.CacheControl, value: file.Folder.CacheControl);
}
HttpContext.Response.Headers.Append(HeaderNames.ETag, etag); HttpContext.Response.Headers.Append(HeaderNames.ETag, etag);
return PhysicalFile(filepath, MimeUtilities.GetMimeType(downloadName)); return PhysicalFile(filepath, MimeUtilities.GetMimeType(downloadName));
} }

View File

@ -62,6 +62,11 @@ namespace Oqtane.Models
/// </summary> /// </summary>
public bool IsSystem { get; set; } public bool IsSystem { get; set; }
/// <summary>
/// An HTTP Caching Cache-Control directive
/// </summary>
public string CacheControl { get; set; }
/// <summary> /// <summary>
/// Deprecated /// Deprecated
/// Note that this property still exists in the database because columns cannot be dropped in SQLite /// Note that this property still exists in the database because columns cannot be dropped in SQLite